POJ 2479

输入:
1 -1 2 2 3 -3 4 -4 5 -5

思路:
这是一个动态规划的问题,满足DP的两个条件:重叠子问题和最优子结构。
采用自底向上的设计策略,先从左至右计算出每个段的最大子序列和a[i],再反过来,从右至左计算每个段的最大子序列和b[i],最后遍历每个段,求出a[i]+b[i]的最大值,即为最后所求值。

代码:

#include <iostream> #include <stdio.h> using namespace std; int x[30][50000]; int y[30];//每个case的长度 int a[30][49999];//存每个段最大值 int a1[30][49999];//存每个段起点 int b[30][49999]; int b1[30][49999]; int GetMaxSubSum(int nCaseNum) { int i,j; int N = y[nCaseNum]; a1[nCaseNum][0] = a[nCaseNum][0] = x[nCaseNum][0]; for (i = 1; i < N-1; i++) { if (x[nCaseNum][i] <= 0) { a[nCaseNum][i] = a[nCaseNum][i-1]; a1[nCaseNum][i] = a1[nCaseNum][i-1] + x[nCaseNum][i]; } else { if (a[nCaseNum][i-1] <= 0) { a[nCaseNum][i] = x[nCaseNum][i]; } else { a[nCaseNum][i] = a1[nCaseNum][i-1] + x[nCaseNum][i]; } a1[nCaseNum][i] = a[nCaseNum][i]; } }//for b1[nCaseNum][N-2] = b[nCaseNum][N-2] = x[nCaseNum][N-1]; for (i = N-3; i >= 0; i--) { if (x[nCaseNum][i+1] <= 0) { b[nCaseNum][i] = b[nCaseNum][i+1]; b1[nCaseNum][i] = b1[nCaseNum][i+1] + x[nCaseNum][i+1]; } else { if (b[nCaseNum][i+1] <= 0) { b[nCaseNum][i] = x[nCaseNum][i+1]; } else { b[nCaseNum][i] = b1[nCaseNum][i+1] + x[nCaseNum][i+1]; } b1[nCaseNum][i] = b[nCaseNum][i]; } } int max = a[nCaseNum][0] + b[nCaseNum][0]; for (j = 0; j < N-1; j++) { int tmp = a[nCaseNum][j] + b[nCaseNum][j]; if (max < tmp) max = tmp; } printf("%d/n",max); return 0; } int main(int argc, char* argv[]) { int nCase; scanf("%d",&nCase); int i,j; for (i = 0; i < nCase; i++) { scanf("%d",&y[i]); for (j = 0; j < y[i]; j++) { scanf("%d",&x[i][j]); a[i][j] = b[i][j] = x[i][j]; a1[i][j] = b1[i][j] = j; } } for (i = 0; i < nCase; i++) { GetMaxSubSum(i); } return 0; }

结果:
最开始的算法用了O(N^2)的时间复杂度,导致Time Limit Exceeded;后来改进了,时间复杂度降为O(N),但提交到POJ出现了Wrong Answer。不知何故,以待研究。

借鉴一下别人的Accepted的代码:
http://fghtech.blogbus.com/logs/62555535.html
在此对博主表示感谢。

你可能感兴趣的:(POJ 2479)