HDU 1024 Max Sum Plus Plus DP中的经典
来源:互联网 发布:java应用服务器有哪些 编辑:程序博客网 时间:2024/06/05 17:50
http://acm.hdu.edu.cn/showproblem.php?pid=1024
Max Sum Plus Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11256 Accepted Submission(s): 3701
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. ^_^
Process to the end of file.
1 3 1 2 32 6 -1 4 -2 3 -2 3
68HintHuge input, scanf and dynamic programming is recommended.
题意:在一个序列中找出最大M段和,子段的长度是任意的(不能为0);
这题由于数据量有点大,要用二维滚动数组来做;
- 但主要还是考DP;
这题是1003最大字段和的升级版。
DP的根本是把一个大问题分解成小问题逐个求解,从中减少重复的计算。
这题要在长度为N的序列中找出M个不重叠的字段,递推过程:
序列:a1,a2,a3......an;已经找出最大M段和max1了,但我现在要在
a1,a2,a3,......,an,a(n+1)中找出最大M段和max2,max1与max2有什么关系么?
这里要分两种情况讨论了,max2中是否包含an+1;
情况1:max2中不包括a(n+1),也就是max2 = max1啦;
情况2:max2中包括a(n+1),这里又要再分两种情况,max1中是否包括an(因为字段是要连续的)
2.1:max1中包含an,所以max2 = max1 + a(n+1);(直接加长包含an的字段)
2.2:max1中不包含an,所以a(n + 1)只能独立成一段,所以就要找出序列
中最大M-1段和max3;max2 = max3 + a(n + 1);
从上面的推导可以看出来,长度为N+1的序列最大M段和(max2)就与长度为N的序
列最大M段和(max1)和长度为N的序列最大M-1段和(max3)有关的;
我们用二维数组来表示这样关系dp[ i ][ j ]表示前 j 个元素中最大 i段和(其中一定
包含aj---最后一个元素);
因为一定包含aj,所以上面情况可以表示为:dp[ i ][ j ] = max (max ( dp[ i - 1 ]
[ k ] ) + a(j) ,dp[ i ][ j - 1 ]+ a(j) );
ps:dp[ i ][ j ]对应递推过程的max2;
max ( dp[ i - 1 ][ k ] ) 对应max3;
dp[ i ][ j - 1 ]对应max1;
在最后完成整个表之后,最大M段和就是max(dp[M][k]);
代码实现:
#include <stdio.h>__int64 num[1000050];__int64 dp[2][1000050];int main (){int i,j,k;int n,m;while (scanf ("%d%d",&m,&n)!=EOF){__int64 max = -99999;int sum = 0;for (i = 1 ; i <= n ; i ++){scanf ("%I64d",&num[i]);dp[0][i] = 0;dp[1][i] = 0;}max = -99999;k = 1;//用作滚动数组的滚动for (i = 1 ; i <= m ; i ++){max = dp[1 - k][i - 1];//这是记录dp[i - 1][j - 1]的最大值dp[k][i] = dp[1 - k][i - 1] + num[i];//此时是相当于dp[i][i];就是全部元素的和;for ( j = i + 1 ; j <= n ; j ++){if (dp[1 - k][j - 1] > max)//这是记录dp[i - 1][j - 1]的最大值max = dp[1 - k][j - 1];dp[k][j] = dp[k][j - 1] +num[j] > max + num[j] ? dp[k][j - 1] + num[j] : max + num[j];}k = 1 - k;}max = -99999999;k = 1 - k;for (i = m ; i <= n ; i ++ )if (dp[k][i] > max)max = dp[k][i];printf ("%I64d\n",max);}}/*1 3 1 2 32 6 -1 4 -2 3 -2 32 5 4 -1 -2 4 12 6 4 -1 -2 4 -1 1*/
- HDU 1024 Max Sum Plus Plus DP中的经典
- HDU 1024 Max Sum Plus Plus 经典 DP
- HDU 1024 Max Sum Plus Plus 经典 DP(A)
- HDU 1024 Max Sum Plus Plus(经典DP)
- hdu 1024 Max Sum Plus Plus--DP
- hdu 1024 Max Sum Plus Plus(dp)
- hdu-1024-Max Sum Plus Plus-DP
- hdu 1024 Max Sum Plus Plus(dp)
- hdu 1024 Max Sum Plus Plus dp
- HDU DP - 1024 Max Sum Plus Plus
- HDU 1024 Max Sum Plus Plus【DP】
- HDU 1024 Max Sum Plus Plus(DP)
- HDU 1024 Max Sum Plus Plus DP
- HDU 1024 Max Sum Plus Plus DP *
- HDU-1024 Max Sum Plus Plus(dp)
- 【hdu 1024】Max Sum Plus Plus dp
- HDU-1024 Max Sum Plus Plus(DP)
- hdu 1024 Max Sum Plus Plus(dp)
- 杭电OJ——1465 不容易系列之一
- POJ 3440
- LibSVM学习(一)——初识LibSVM
- 2012总结--第10篇--工作篇
- hdu 2544最短路 Floyd算法
- HDU 1024 Max Sum Plus Plus DP中的经典
- BMP文件格式简介
- mysql的各种乱码问题
- 《C++ Primer》 第10章 关联容器
- 举例分析Java对象的初始化过程
- 预备知识
- Likelihood 统计学中可能性的定义
- 125亿元!华为公开晒年终奖
- Google开源实时通信项目WebRTC