题目
题解
经典动态规划之一。
dp[i]
表示以第i
个元素结尾的子序列的最大值;
转移方程:当dp[i-1]>0
时,前i个元素且以第i
个元素结尾的最大子序列肯定要加上dp[i-1]
,因为dp[i-1]
可以对答案做出正贡献,因此dp[i] = a[i] + dp[i-1]
;要是dp[i-1]<=0
,则加上dp[i-1]
只会对答案做出负贡献,因此dp[i] = a[i]
,与a[i]
的正负无关,因为dp[i]
表示的就是以第i
个元素结尾的子序列的最大值,必然包含a[i]
。
第二个代码思路还是动态规划,只不过没用数组实现更省空间而已。
代码1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll ans, x, n, dp[N];
int main()
{
cin>>n;
for(int i = 1;i <= n;i ++) {
cin>>x;
if(dp[i-1] > 0) dp[i] = dp[i-1] + x;
else dp[i] = x;
ans = max(ans, dp[i]);
}
cout << ans << endl;
return 0;
}
代码2
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
ll sum, ans, x, n;
int main()
{
cin>>n;
for(int i = 1;i <= n;i ++) {
cin>>x;
if(sum < 0) sum = x;
else sum += x;
ans = max(ans, sum);
}
cout << ans << endl;
return 0;
}