[kuangbin带你飞]专题1-23 Max Sum Plus Plus HDU - 1024

总结:DP思想

原题链接:https://vjudge.net/problem/HDU-1024

Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.


Given a consecutive number sequence S 1, S 2, S 3, S 4 ... S x, ... S n (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ S x ≤ 32767). We define a function sum(i, j) = S i + ... + S j (1 ≤ i ≤ j ≤ n).

Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i 1, j 1) + sum(i 2, j 2) + sum(i 3, j 3) + ... + sum(i m, j m) maximal (i x ≤ i y ≤ j x or i x ≤ j y ≤ j x is not allowed).

But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(i x, j x)(1 ≤ x ≤ m) instead. ^_^

 

 

Input:Each test case will begin with two integers m and n, followed by n integers S 1, S 2, S 3 ... S n.
            Process to the end of file.


Output:Output the maximal summation described above in one line.


Sample Input

1 3 1 2 3
2 6 -1 4 -2 3 -2 3

Sample Output

6
8

思路讲解:一开始会又想要采用二维数组的写法采用dp[i][j]来进行存储前i个数分为j块的情况
那么将分为dp[i][j]将取三个值中的最大值 dp[i-1][j]+a[i](加载最后一组里) dp[i-1][j-1](舍弃掉这个数) dp[k][j-1]+a[i](新开一组)
但是由于题目达到1000006 数组无法放下 所以开一个数组a[j]并开两个循环来进行模拟
具体看注释

 ac代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdio.h>
 6 using namespace std;
 7 int a[1000005],dp[1000005],temp[200005];
 8 int main()
 9 {
10     int n,m,i,j;
11     while(scanf("%d%d",&m,&n)!=EOF)
12     {
13         memset(dp,0,sizeof(dp));
14         memset(temp,0,sizeof(temp));
15         memset(a,0,sizeof(a));
16         for(i=1;i<=n;i++)//输入 
17             scanf("%d",&a[i]);
18         int ans;
19         for(i=1;i<=m;i++)//i来代表分为多少块 从1块开始 
20         {
21             ans=-99999999;//这里最开始是为了将每次划分的最开始设为极小值在后面更新划分 
22             for(j=i;j<=n;j++)//j表示前j个数分为i块的最大值 j应当大于i 
23             {
24                 //dp表示分为i块前j数的最大值   temp为分为i-1块前j数最大值 
25                 dp[j]=max(dp[j-1]+a[j],temp[j-1]+a[j],);
26                 temp[j-1]=ans;
27                 ans=max(ans,dp[j]);//与不加j的值进行比较 并对此时的最优值进行赋值 
28             }
29         }
30         cout<<ans<<endl;
31     }
32 }

 

posted @ 2020-05-29 14:32  cszdrg  阅读(72)  评论(0)    收藏  举报