传送门:hdu 1231 最大连续子序列
解题思路
首先我们先要确定一下状态方程,
我们必须先要找到哪个子序列的和最大,所以dp[i]里面保存的是前i-1个中子序列中和最大的。
所以状态方程就能写出:dp[i] = max(a[i],dp[i-1]+a[i])
其中a[i]表示的是输入的第i个数,如果a[i]<0的话,肯定是dp[i] = a[i]的所以这样就能保存了前i-1个中子序列的和的最大。通过上面保存下来dp[i]这个数组中最大值的下标。
然后在通过逆过程计算出这个和的最大值的左端下标。
AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int n;
int seq[50000];
int dp[50000];
while(~scanf("%d",&n) && n)
{
for(int i=1;i<=n;i++){
scanf("%d",&seq[i]);
}
int left=1,right=1;
int amount = seq[1];
memset(dp,0,sizeof dp);
dp[1] = 0;
//这个循环计算出任何子序列中的最大值
for(int i=2;i<=n;i++){
dp[i] = max(seq[i],dp[i-1]+seq[i]);
if(dp[i]>amount){
right = i;
amount = dp[i];
}
}
int sum=0;
//然后通过逆过程,找到最大值所对应的左下标
for(int i=right;i>0;i--){
sum += seq[i];
if(sum == amount){
left = i;
break;
}
}
if(amount<0){
printf("0 %d %d\n",seq[1],seq[n]);
continue;
}
printf("%d %d %d\n",amount,seq[left],seq[right]);
}
}