标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231
这道题是一道最大连续子序列的模板题,但是它要求输出首尾元素,那么如何找到首尾元素是关键,最大子序列的尾元素比较好找,记录最大的dp,该序号就是最大结点的序号,最小元素序号逆推,当dp第一次小于0的时候,它的下一个元素一定开启了新的一段。注意一下和为0的情况这种特殊情况判断。
动态转移方程为
B[K] = MAX(B[K-1]+A[K] , A[K])(B[K]为以k为最后元素的最大和,那么它的由来是由这俩个状态得来,一个是前第k个元素和第k-1个元素为一组,这个条件就要求B[k-1]大于0,如果是B[k-1]小于0,那么明显第k个元素重新另起一段,既A[k]会更大。。就这俩种情况!)
ac代码如下:
#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> #include <stack> #include <queue> #include <map> #include <vector> #include <cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn = 15555; int dp[maxn], va[maxn]; int main(void) { //freopen("in.txt", "r", stdin); int K, i; while (scanf("%d", &K) != EOF&&K) { for (i = 1; i <= K; i++) scanf("%d", &va[i]); memset(dp, 0, sizeof(dp)); int maxx = -0x3f3f3f3f, pos, poss; for (i = 1; i <= K; i++) { dp[i] = max(dp[i - 1] + va[i], va[i]); if (dp[i]>maxx) { pos = i; maxx = dp[i]; } } for (i = pos; i >= 1; i--) { if (dp[i] < 0) //当dp小于0的时候,后面的元素一定是开始了新的一段了 { poss = i+1; break; } } if (i == 0) { poss = 1; } if (maxx <0) printf("0 %d %d\n", va[1], va[K]); else printf("%d %d %d\n", maxx, va[poss], va[pos]); } return 0; }
标签:
原文地址:http://blog.csdn.net/yizhen_acmer/article/details/51360154