POJ 2479 初步线性 DP
2013-08-15 09:34
295 查看
//Maximum sum// //题目链接:http://poj.org/problem?id=2479 /* DP思想: 题目是要求一个序列的最大的两个不想交的子段和。既然要求两个子段的和想加是最大的,那么显然,两个子段和在相加之前都应该是最大的,既然是不想交的两个 子段,那么我就枚举序列中的每一个位置,在它的左边求左边子段的和,在它的右边求右边子段的和,之后筛选出,每个位置的左边子段和的最大值和右边子段和的最大值 分别存在left right 数组里面,最后 遍历所有的位置的左右子段和最大值相加,求出最大的一个,即可得出结果。 虽然没有用到很实际的DP东西,但是DP的思想这里已经有了,问题已经符合最有子结构的性质(求每一个位置的左或右的最大子段和的时候,都要依赖之前位置所求出到的结果),而且在你求解左边子段的最大和的时候,子问题也会重叠()。满足这两个性质 用DP是最好不过的 */ #include<stdio.h> #include<string.h> #define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define MIN -9999999 int num[55555]; int left[55555]; int right[55555]; int main() { int T; int n,i,j,k; int sum; while(scanf("%d",&T)!=EOF) { while(T--) { sum=0; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&num[i]); left[1]=num[1]; for(i=2;i<=n;i++) //子问题求解,分别求每个位置的左边的最大 字段和// { if(left[i-1]<0) left[i]=num[i]; else left[i]=left[i-1]+num[i]; } for(i=2;i<=n;i++) left[i]=max(left[i-1],left[i]); //此时的left[i]就是i位置左边的最大子段和。 right =num ; for(j=n-1;j>=1;j--) //同理上面,求右边的最大字段值// { if(right[j+1]<0) right[j]=num[j]; else right[j]=right[j+1]+num[j]; } for(j=n-1;j>=1;j--) right[j]=max(right[j+1],right[j]); sum=MIN; for(i=2;i<=n;i++) //枚举所有的位置的所有子段最大和相加,求出最大的给sum// sum=max(sum,left[i-1]+right[i]); printf("%d\n",sum); } } return 0; }
相关文章推荐
- POJ 2479 - Maximum sum(线性DP)
- POJ 2479-Maximum sum(线性dp)
- POJ - 2479 《Maximum sum》 【线性DP】
- POJ 2479-Maximum sum(线性dp)
- POJ2479【线性DP】
- [poj 3666] Making the Grade (离散化 线性dp)
- POJ-2533 Longest Ordered Subsequence (线性dp 最长上升子序列)
- 简单的dp@poj(2)2479最大子段和
- poj1185炮兵布阵结题报告--初步了解--状态压缩dp
- POJ 2250 Compromise (线性dp LCS +递归路径)
- poj 1141 Brackets Sequence(线性dp)
- poj-2479 Maximum sum DP
- POJ 2479 + POJ 2593(DP 最大双子序列 ^_^)
- POJ2479 Maximum sum 最长连续子序列[DP]
- POJ-1952 BUY LOW, BUY LOWER(线性DP)
- POJ 1958 Strange Towers of Hanoi (线性dp 推公式)
- poj 2479 Maximum sum 【DP】
- POJ 2385 Apple Catching(线性DP)
- POJ2479 Maximum sum 最长连续子序列[DP]
- poj-2479 简单DP