HDU1024 Max Sum Plus Plus
来源:互联网 发布:日本中国夏令营知乎 编辑:程序博客网 时间:2024/05/16 09:54
Max Sum Plus Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24256 Accepted Submission(s): 8313
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. ^_^
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.
Process to the end of file.
Output
Output the maximal summation described above in one line.
Sample Input
1 3 1 2 32 6 -1 4 -2 3 -2 3
Sample Output
68HintHuge input, scanf and dynamic programming is recommended.
Author
JGShining(极光炫影)
思路:用dp[i][j]表示将j个数字分成i段,并且最后一段以numb[j]结尾的最大和,那么dp[i][j]的来源情况只有两种:
1.将前j-1个数分成i段,然后把这个数直接接在最后一段,那么dp[i][j] = dp[i][j-1] + numb[j].
2.将前j-1个数分成i-1段,然后再将第j个数变成独立的一段 那么dp[i][j] = max(dp[i-1][k])(i-1<=k<j)
综上可以得到转移方程:dp[i][j] = max( dp[i][j-1] + numb[j], max(dp[i-1][k])(i-1<=k<j) )
但是n的范围是1e6,显然开二维数组是不行的,需要优化一下。
优化:发现dp[i][j] 之和dp[i][j-1]以及dp[i-1][k]有关,我们可以用一个一维数组,每次滚动记录dp[i][j].
但是这样的话,寻找max(dp[i-1][k])还需要遍历一遍,显然是不合理的,所以我们再开一个数组pre[j]记录max(dp[i-1][k])(i-1<=k<j).
这样我们便可以每次直接读取这个值即可。
#include <vector>#include <map>#include <set>#include <queue>#include <stack>#include <algorithm>#include <sstream>#include <iostream>#include <cstdio>#include <cmath>#include <cstdlib>#include <cstring>#include <string>#if defined(_MSC_VER) || __cplusplus > 199711L#define aut(r,v) auto r = (v)#else#define aut(r,v) __typeof(v) r = (v)#endif#define each(it,o) for(aut(it, (o).begin()); it != (o).end(); ++ it)#define fur(i,a,b) for(int i=(a);i<=(b);i++)#define furr(i,a,b) for(int i=(a);i>=(b);i--)#define cl(a) memset((a),0,sizeof(a))#define mp make_pair#define pb push_back#define fi first#define se second#define sc(x) scanf("%d",&x)using namespace std;typedef long long ll;typedef unsigned long long ull;typedef pair <int, int> pii;const int inf=0x3f3f3f3f;const double eps=1e-8;const int mod=1000000007;const double pi=acos(-1);inline void gn(long long&x){ int sg=1;char c;while(((c=getchar())<'0'||c>'9')&&c!='-');c=='-'?(sg=-1,x=0):(x=c-'0'); while((c=getchar())>='0'&&c<='9')x=x*10+c-'0';x*=sg;}inline void gn(int&x){long long t;gn(t);x=t;}inline void gn(unsigned long long&x){long long t;gn(t);x=t;}inline void gn(double&x){double t;scanf("%lf",&t);x=t;}inline void gn(long double&x){double t;scanf("%lf",&t);x=t;}int gcd(int a,int b){return a? gcd(b%a,a):b;}ll powmod(ll a,ll x,ll mod){ll t=1ll;while(x){if(x&1)t=t*a%mod;a=a*a%mod;x>>=1;}return t;}// (づ°ω°)づe★int numb[1000005];int dp[1000005];int pre[1000005];void init(){ cl(dp); cl(pre);}int n,m; int main(){ int tmp; while(~scanf("%d %d",&m,&n)){ init(); fur(i,1,n)gn(numb[i]); fur(i,1,m){ tmp = -inf; fur(j,i,n){ dp[j] = max(dp[j-1],pre[j-1]) + numb[j]; pre[j-1] = tmp; //因为计算到dp[j]的时候 ,需要用到pre[j-1] tmp = max(dp[j],tmp); //所以我们不能在获得dp[j-1]的时候立刻更新pre[j-1] } //而是先临时保存一下这个值 } //当计算完dp[j]以后再修改dp[j-1]; printf("%d\n",tmp); //因为最大的值不一定是以numb[n]结尾的 } //所以不能输出 dp[n] 而是应该输出dn[i]里面最大的那个 return 0;}
0 0
- hdu1024-Max Sum Plus Plus
- hdu1024 Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- HDU1024--Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- hdu1024 Max Sum Plus Plus
- hdu1024---Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- hdu1024 Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus
- hdu1024 Max Sum Plus Plus
- Max Sum Plus Plus||HDU1024
- HDU1024-Max Sum Plus Plus
- hdu1024 Max Sum Plus Plus
- HDU1024 Max Sum Plus Plus 【DP】
- HDU1024 Max Sum Plus Plus(DP)
- CSS学习之列表 - CSS: The Missing Manual
- java.sql.SQLException:Value '0000-00-00' can not be represented as java.sql
- Android Studio在NDK开发的时候,无法生成so文件
- mysql数据库中的自增字段会不会溢出,我用的是int,万一超过这个int的表示范围会怎样
- socket详解
- HDU1024 Max Sum Plus Plus
- android开发 程序去掉标题栏按菜单键程序崩溃
- 激光散斑原理总结
- java并发编程实战-对象的共享
- 利用jsp+uploadify插件实现附件下载
- ios emoji表情的保存
- 利用MediaRecoder类进行音频录制,自己试试哦
- Android Studio 图片报错问题
- iOS歌词渐变的实现