PAT甲级题目1007 Maximum Subsequence Sum

题目大意:
给出一个K个整数的数列,一个连续的子序列被定义为**{Ni,Ni+1,…,Nj} &&1<=i<=j<=K**,最大子序列是有最大元素和的连续子序列,求出这个连续子序列的和,第一个元素,最后一个元素。

输入:
①第一行一个正整数K
②第二行K个整数

输出:
这个连续子序列的和,第一个元素,最后一个元素。
**要求:**若这个最大子序列不是唯一的,输出顺序最小的。
如果K个数字都是负数,输出0,原序列第一个元素,最后一个元素

思路:
动态规划,设置一个数组num存放这K个数字,dp存放最大子序列的和。
dp[i]存放以num[i]结尾的最大子序列的和。
状态转移方程:dp[i]=max(num[i],dp[i-1]+num[i])

代码:

#include
#include
using namespace std;
int n;
int num[10005];
int dp[10005];
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    scanf("%d",&num[i]);
    dp[0]=num[0];
    for(int i=1;i<n;i++)
    {
        dp[i]=max(dp[i-1]+num[i],num[i]);
    }
    int k=0;
    for(int i=1;i<n;i++)//从小到大枚举,求出最小顺序的最大子序列
    {
        if(dp[i]>dp[k])
        k=i;
    }
    if(dp[k]<0)
    {
        printf("0 %d %d\n",num[0],num[n-1]);//最大子序列的和为负,原序列肯定全是负数
    }
    else
    {
        int sum=0;
        int index;
        for(int i=k;i>=0;i--)
        {
            sum+=num[i];
            index=i;
            if(sum==dp[k])
            {
                printf("%d %d %d\n",dp[k],num[index],num[k]);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(PAT甲级题目,动态规划,数据结构,算法)