HDU_1231(最大连续子序列)

题目链接: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;
}

你可能感兴趣的:(HDU_1231(最大连续子序列))