1. 程式人生 > >hdu1024 動態規劃

hdu1024 動態規劃

題意是給你個數字序列,現在讓你把這個序列分成m個連續的子序列,且要求這m個子序列的累加和最大。

思路:這道題的題意可以理解為問在序列為末尾時,把序列分為m個子序列這個狀態時的最大累加和,那麼可以得出這個狀態應該是由上一個狀態轉移得來:(因為dp[i][j]表示數到第j個字元時,前j個數字序列被分為i組時的最大值)dp【i][j]=max(dp[i-1][j]+num[j],dp[i][j-1]+num[j])這兩種狀態,第一種轉移狀態意思是第j個數字合併到上一個分組中構成新的分組,第二個狀態是第j個數字自己構成一個分組;

程式碼:

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 1e6 + 10;
const int inf = 0x7ffffff;
int dp[maxn], pre[maxn];//dp[i]表示第i個位置的最大累加和,pre[i]表示i前面的數字的最大累加和;
int num[maxn];

int main()
{
		int n, m;
		while (scanf("%d %d", &m, &n) != EOF)
		{
				memset(dp, 0, sizeof(dp));
				memset(pre, 0, sizeof(pre));
				for (int i = 1; i <=n; i++)
						scanf("%d", &num[i]);
				int temp;
				for (int i = 1; i <= m; i++)
				{
						temp = -inf;
						for (int j = i; j <= n; j++)
						{
								dp[j] = max(dp[j - 1], pre[j - 1])+num[j];
								pre[j-1] = temp;
								temp = max(temp, dp[j]);
						}
				}
				printf("%d\n", temp);
		}
		system("pause");
		return 0;
}