m大子段和 hdu1024
给出n个数,m个区间;
求选区m个区间的最大值;
1 #include<cstdio> 2 #include<algorithm> 3 #include<math.h> 4 #include<queue> 5 using namespace std; 6 int d[maxn]; 7 int pre[maxn]; 8 int main() 9 { 10 int m,n,tmp; 11 while(cin>>m>>n){ 12 int tmp; 13 for(int i=1;i<=n;++i){ 14 cin>>num[i]; 15 } 16 //d[j]:第j个人放在第i组时的最大值(1<=i<=j<=n,1<=i<=m)(一定要有j); 17 //pre[j]:第前J个人中的最大值,可以不包括j; 18 memset(d,0,sizeof(d)); 19 memset(pre,0,sizeof(pre)); 20 //此代码采用滚动的方式,所以只有一维; 21 //本来面目应该是dp[j][i]:表示前j个数分成i段的情况; 22 for(int i=1;i<=m;++i){ //这一波循环就是才用滚动的方式降维; 23 //为什么要降维(因为本题会超内存 hdu 1024) 24 tmp=-inf; 25 for(int j=i;j<=n;++j){ 26 //dp[j] 求出的是在有 i 个段的情况下,包括j的前j个数中的最大值。 27 //此for循环里,d[j]是从此次循环的"d"和上一次循环完成的“pre[]”作为转化条件; 28 //因为在本循环的更新中,d[j-1]+num[j]得出的值可能比较大;所以也要作为一个选择的条件。 29 //而假如num[j]是负数,就会选择pre[j-1]+num[j] 30 d[j]=max(d[j-1],pre[j-1])+num[j]; 31 //而这一次循环里的d[j]求出的值,会放到pre这个数组里, 32 //会跟之前的tmp择优作为下一轮滚动的条件; 33 pre[j-1]=tmp; 34 tmp=max(tmp,d[j]); 35 } 36 } 37 cout<<tmp<<endl; 38 } 39 return 0; 40 }