MAX SUM(HDU_1003——dp)
题目:
题意: 让求给出的序列中连续的一个子序列的和的最大值,以及这个子序列的起点和终点。
思路:dp求当前位置的最大值,dp[i] = max(dp[i-1], a[i]);最大值的位置就是终点,既然知道了和的大小,那么,只要找出那个区间的和是该值就可以了,这里可以用一个前缀和数组来求开始的位置。
ps:dp还是得多思考、多练啊!!
代码:
#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <map>
#include <vector>
#define INF 0x3f3f3f3f
#define FRE() freopen("in.txt","r",stdin)
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int a[maxn],dp[maxn],sum[maxn];
int main()
{
int T,n,cnt = 1;
scanf("%d",&T);
while(T--)
{
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
memset(sum,0,sizeof(sum));
scanf("%d",&n);
for(int i = 1; i<=n; i++)
{
scanf("%d",&a[i]);
sum[i] = sum[i-1]+a[i];
}
int st = 0,en = 0,mmax = -INF,f = 1;
for(int i = 1; i<=n; i++)
{
dp[i] = max(dp[i-1]+a[i],a[i]);
if(dp[i]>mmax)
{
mmax = dp[i];
en = i;
}
}
for(int i = 1; i<=en; i++)
{
if(sum[en]-sum[i-1] == mmax)
{
st = i;
break;
}
}
if(cnt!=1)printf("\n");
printf("Case %d:\n",cnt++);
printf("%d %d %d\n",mmax,st,en);
}
return 0;
}
/*
样例输入:
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
样例输出:
Case 1:
14 1 4
Case 2:
7 1 6
*/