首页 > 其他 > 详细

hdu 1024 Max Sum Plus Plus

时间:2019-03-04 21:20:32      阅读:172      评论:0      收藏:0      [点我收藏+]

Max Sum Plus Plus

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 40437    Accepted Submission(s): 14558


Problem Description
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 S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (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(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx 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(ix, jx)(1 ≤ x ≤ m) instead. ^_^
 

 

Input
Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
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
Hint
Huge input, scanf and dynamic programming is recommended.
 
 
 
题意:让你求的是从n个数中选取m个部分后所能得到的最大子段和,且m个部分不能有相交的部分(如,sum(2,4)//第二个到第四个+sum(3,5)//第三个到第五个就不行)。
写不出,人菜没办法,唉。
详解在代码中(看别人代码后写的)。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 #define LL long long
 5 #define mem(a,b) memset(a,b,sizeof(a))
 6 using namespace std;
 7 LL dp[2][1000010];//dp[i][j]=k是i是分i段,j是前j个数,k是前j个数分i段的最大值 
 8 //dp[i][j]=max(dp[i][j-1]//不选第j个数,max(dp[i-1][k]/i-1<=k<j,dp[i][j-1])+第j个数//选第j个数) ,答案是dp[m%2][n];
 9 //可优化:即 1:dp[i-1][k]/i-1<=k<j,可用一个变量记录它
10 //            2: 只有dp[i][j-1]和dp[i-1][j-1]用得到,所以只需一维开2这么大就行 
11 int num[1000010];
12 LL up_max;
13 int main(){
14     int m,n;
15     int k;
16     while(~scanf("%d%d",&m,&n)){
17         mem(dp,0);
18         mem(num,0);
19         up_max=0;
20         for(int i=1;i<=n;i++){
21             scanf("%d",&k);
22             num[i]+=num[i-1]+k;
23         }
24         int t=0;
25         for(int i=1;i<=m;i++){
26             for(int j=i;j<=n;j++){
27                 if(i==j){
28                     up_max=dp[t][j]=num[j];//**!!!!*给dp赋初值,如果不写,则dp的第一个可能会是重j-1个数中选出i种,但是i==j只有从j个数中才可选出i种 
29                     //up_max是每一个重j-1分i段的最大和,所以也要赋初值 
30                 }else{
31                     up_max=max(up_max,dp[1-t][j-1])+num[j]-num[j-1];
32                     dp[t][j]=max(dp[t][j-1],up_max);
33                 }
34             }
35             t=1-t; //让数组一维滚动交换为(0,1)
36         }
37         t=1-t;//最后多减了一次,再减一下
38         cout<<dp[t][n]<<endl;
39     }
40     return 0; 
41 }

2019-03-04

21:08:22

hdu 1024 Max Sum Plus Plus

原文:https://www.cnblogs.com/liuzuolin/p/10473217.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!