一道dp。
思路:对于序列中的一个点i,有两种考量
一是继承前面的序列和
二是自己开始
最关键的点在于,之前的序列和是否大于或等于0。若是小于零,对于点i来说,之前的完全没有用。所以:dp[i] = max(dp[i -1] + num[i[, num[i])。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100000 + 5;
int num[maxn];
int dp[maxn];
int main()
{
int T;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++)
{
int start, last, beg ;
start = last = beg = 0;
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d", &num[i]);
int maxsum = num[0];
dp[0] = num[0];
for(int i = 1; i < n; i++)
{
if(dp[i - 1] >= 0)//注意是答案是第一个出现的最优序列,我们是从前开始的,要把等于零的算上。
{
dp[i] = dp[i - 1] + num[i];
}
else
{
dp[i] = num[i];
beg = i;
}
if(dp[i] > maxsum)
{
start = beg;
last = i;
maxsum = dp[i];
}
}
if(kase > 1) printf("\n");
printf("Case %d:\n", kase);
printf("%d %d %d\n", maxsum, start + 1, last + 1);
}
return 0;
}