这题做过一次, 第二次写还是出现了问题。
就连最基本的状态方程都写错了, 超级尴尬。
DP真心不是我的菜, 太难去理解, 太难去实现了。
这个真是莫大的教训啊, 看来以后做过了的题得多做几遍了, 不能就做2遍。
#include <iostream>
#include <string>
using namespace std;
int dp[100010], a[100010], start[100010];
int main()
{
int T, n;
int i, k, end, sum;
scanf("%d", &T);
for (k = 1; k <= T; k++)
{
scanf("%d", &n);
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
start[0] = 1;
memset(dp, 0, sizeof(dp));
for (i = 1; i <= n; i++)
{
//dp[i-1] 一定 >= 0
if (dp[i-1] + a[i] >= a[i])
{
dp[i] = dp[i-1] + a[i];
//当前起点即上一状态起点
start[i] = start[i-1];
}
//a[i] < 0
else
{
dp[i] = a[i];
//起点变更
start[i] = i;
}
}
sum = -1;
for (i = 1; i <= n; i++)
{
if (sum <= dp[i])
{
sum = dp[i];
end = i;
}
}
printf("Case %d:\n%d %d %d\n", k, sum, start[end], end);
if (k != T) printf("\n");
}
return 0;
}
又做了遍, 0MS AC
#include <iostream>
#define INF 100000
using namespace std;
int main()
{
int T, n, a, dp[100010];
int i, k, MAX, begin, start, end;
scanf("%d", &T);
for (k = 1; k <= T; k++)
{
scanf("%d", &n);
memset(dp, 0, sizeof(dp));
MAX = -INF;
begin = 1;
for (i = 1; i <= n; i++)
{
scanf("%d", &a);
if (dp[i-1] >= 0)
dp[i] = dp[i-1] + a;
else
{
dp[i] = a;
begin = i;
}
if (MAX < dp[i])
{
MAX = dp[i];
start = begin;
end = i;
}
}
printf("Case %d:\n%d %d %d\n", k, MAX, start, end);
if (k != T)
printf("\n");
}
return 0;
}