https://www.acmicpc.net/problem/1912
1912번: 연속합
첫째 줄에 정수 n(1 ≤ n ≤ 100,000)이 주어지고 둘째 줄에는 n개의 정수로 이루어진 수열이 주어진다. 수는 -1,000보다 크거나 같고, 1,000보다 작거나 같은 정수이다.
www.acmicpc.net
1 . ox를 그때그때 선택해버리기
1.완탐 : i번째수를 선택함, 안함으로 2^n 탐색해야함
2. 선택한경우 vs 선택안한경우에서 최적인 경우를 그때그떄 선택한다.
3. 이전값 + 현재값() vs 현재값(나부터 연속합 새로시작) 중에 큰값을 선택하면 된다.
2.전체코드
#include <bits/stdc++.h>
using namespace std;
long long d[100004], a[100004],n;
//d[i]: i자리까지 연속합중 최대값
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
d[i] = a[i];
}
d[1] = a[1];
for (int i = 2; i <= n; ++i) {
d[i] = max(a[i], d[i - 1] + a[i]);
//d[i]=max(현재값[새로시작], 이전값+현재값)
}
//각각 i자리까지의 최대값이 저장됨
//d[n]이 최대값 보장이아님 -> 최대값찾으면됨.
cout << *max_element(d + 1, d + n + 1);
}
* 25.2.17 내 풀이 (dp)
- 다버리고 나부터 새로시작 vs 이전걸 이어받을건지 비교
#include<bits/stdc++.h>
using namespace std;
int n;
int dp[100000+4], a[100000+4];
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n;
for(int i=0;i<n;++i) {
cin>>a[i];
}
dp[0]=a[0];
for(int i=1;i<n;++i) {
if(dp[i-1]+a[i] < a[i]) {
dp[i]=a[i];
}
else {
dp[i]=dp[i-1]+a[i];
}
}
cout<<*max_element(dp,dp+n);
}
* 큰돌풀이(그리디)
- 누적합이 음수라면 버리는 방식
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int n, sum, a, ret = -1001;
int main(){
scanf("%d", &n);
for(int i = 0; i < n; i++){
scanf("%d", &a);
sum += a;
ret = max(ret, sum);
if(sum < 0) sum = 0;
}
printf("%d\n", ret);
return 0;
}
'Algorithm > dp' 카테고리의 다른 글
백준 1699 제곱수의 합 c++ // dp 2차원 to 1차원, 수학으로 시간복잡도줄이기 (0) | 2024.04.16 |
---|---|
백준 11052 카드구매하기 c++ //dp 관찰방법 (0) | 2024.04.15 |
백준 11053 LIS c++ // dp, 규칙발견, 일반화 (0) | 2024.04.15 |
백준 1520 내리막길 c++ // top-down dp, dfsDp, 상하좌우탐색 문제점 (0) | 2024.04.10 |
백준 1890 점프 c++ // dp, 배열순회dp, dp[next] += dp[cur] (0) | 2024.04.08 |