最大子段和问题[DP]
给出一个长度为 nn 的序列 aa,选出其中连续且非空的一段使得这段和最大。
b[i]=max(b[i-1]+a[i],a[i])
第一个数为一个有效序列
如果一个数加上上一个有效序列得到的结果比这个数大,那么该数也属于这个有效序列。
如果一个数加上上一个有效序列得到的结果比这个数大,那么该数也属于这个有效序列。
如果一个数加上上一个有效序列得到的结果比这个数小,那么这个数单独成为一个新的有效序列}- 如果一个数加上上一个有效序列得到的结果比这个数小,那么这个数单独成为一个新的有效序列
7
2 -4 3 -1 2 -4 3
#include<bits/stdc++.h>
using namespace std;
int n,f[200020],k[200020],i,ans=-INT_MAX;
int main()
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>k[i];
if(i<1)f[i]=k[i];
else f[i]=max(f[i-1]+k[i],k[i]);
ans=max(f[i],ans);
}
cout<<ans;
return 0;
}
滚动数组???
减少空间
#include<bits/stdc++.h>
using namespace std;
int n,k,f[2],i,ans=-INT_MAX;
int main()
{
cin>>n;
cin>>k;
f[0]=k;
for(i=1;i<n;i++)
{
cin>>k;
f[i&1]=max(k,f[!(i&1)]+k);//滚动数组f[2]
ans=max(f[i&1],ans);
}
cout<<ans;
return 0;
}
//代码里的位运算&1 可以看做是 %2 。
//而加上感叹号就是 0变1 , 1变0