- 题目链接
- 这是一道简单的动态规划问题。题目意思即为求最大的子序列和。可将数据储存在一个数组中,然后对其进行处理。思路:数组为dp[n],即有n个数据。先假设max-sum = dp[0],并记录初始位置,末位置,和定义一个变量记录初始位置。采用一个n次的循环。循环内的操作为(如果此时循环变量为 i) : 如果dp[i-1] > 0 ,dp[i] = dp[i] + dp[i-1],(具有记录字符序列和的作用),不然的话,抛弃dp[i-1],更新起始位置。接着如果当前序列和dp[i]>max-sum,则将max-sum = dp[i],并记录初始位置和末位置。
- 状态转移方程:dp[i] = MAX(dp[i – 1] + dp[i], dp[i]) (n>=2)
#include <stdio.h> /* HDU 1003 Max Sum --- 经典DP */
#include <string.h>
int dp[100005];
int main()
{
#ifdef _LOCAL
freopen("D:\\input.txt", "r", stdin);
#endif
int t, n;
int Case = 0;
int fst, lst, maxSum; //记录首位位置以及最大和
int start; //start是用于记录中间变化的起点的
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
scanf("%d", &dp[i]);
}
start = fst = lst = 0;
maxSum = dp[0];
for (int i = 1; i < n; ++i)
{
//dp[i] = MAX(dp[i - 1] + dp[i], dp[i]);
//由于是从前往后更新的,可以省下一个dp数组
if (dp[i-1] >= 0)
{
dp[i] = dp[i - 1] + dp[i];
}
else
{
start = i; //抛弃dp[i-1],则起点发生变化
}
if (dp[i] > maxSum)
{
//若当前求得的子序列和最大,进行更新
maxSum = dp[i];
fst = start;
lst = i;
}
}
if (Case)
{
printf("\n");
}
printf("Case %d:\n", ++Case);
printf("%d %d %d\n", maxSum, fst+1, lst+1);
}
return 0;
}