hdu 1231 最大连续子序列 DP

来源:互联网 发布:linux jdk 7u80 编辑:程序博客网 时间:2024/04/29 15:33

传送门: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]);    }}
1 0
原创粉丝点击