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 }

 

posted @ 2019-10-05 21:42  古比  阅读(184)  评论(0编辑  收藏  举报