标签:
题目链接: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