这道题应该是第一次做的dp题,虽然以前可能乱做题做到过要用到dp的题,但这道题是开始!
网上找了篇博客,看了下dp的思想,不得不说真的是自己见识短浅,太巧妙了。
摘自他人博客:
题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置
解题思路:经典DP,可以定义dp[i]表示以a[i]为结尾的子序列的和的最大值,因而最大连续子序列及为dp数组中的最大值。
状态转移方程:dp[1] = a[1]; //以a[1]为结尾的子序列只有a[1];
i >= 2时, dp[i] = max( dp[i-1]+a[i], a[i] );
dp[i-1]+a[i] > a[i]时,即dp[i-1]的值为正,那么dp[i-1]则对dp[i]有贡献,
dp[i-1]+a[i] < a[i]时,即dp[i-1] < 0,那么抛弃它,dp[i] = a[i]
例子:序列 6 -7 5 2 -3, 则dp[i]分别为 6 -1 5 7 4,注意dp[2]直接用a[2]表示,因为dp[1] = -1 < 0; 最后最大子序列和即为dp数组中的最大值 5;
至于位置的记录,则再每次获取到最大值时更新即可。另外此题是从前往后更新,可直接使用a[i]数组而省下一个dp数组。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct {
int sum;
int start;
int end;
}dp[100050];
int main()
{
int i,t,j