Max Sum Plus Plus---hdu1024(动态规划求M段的最大和)
Posted 西瓜不懂柠檬的酸
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Max Sum Plus Plus---hdu1024(动态规划求M段的最大和)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024
题意就是有n个数分成m段,求最大的和;
dp[i][j]表示把 j 个数分成 i 段,选择第 j 个数的结果,而并不是当前的最优解,
那么要考虑的是第i个数的数是自己成一段还是和前面的成一段
所以dp[i][j]=max(dp[i][j-1]+a[j], Max+a[j]); 其中Max为前 j-1 个数字分成 i-1 段中的最大值;
由于题中n为100w,m不知道是多少,所以开二维数组可能不行因为只有每个状态就只和它的前一个状态有关,所以我们可以用dp【2】【N】来实现滚动数组;
异或^是相同为0,不同为1,可以用^1来转换状态;
本题要考虑边界问题;
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define N 1000050 #define MOD 1000000007 #define met(a, b) memset(a, b, sizeof(a)) #define INF 0x3f3f3f3f typedef long long LL; int n, m, dp[2][N], a[N]; int main() { while(scanf("%d %d", &m, &n)!=EOF) { met(dp, 0); met(a, 0); for(int i=1; i<=n; i++) scanf("%d", &a[i]); int Max, ans, k; k = 0; for(int i=1; i<=m; i++) { k = k^1; dp[k][i] = dp[k^1][i-1]+a[i];///选择第i个数,分成i段,所以只能自己成一段,那么只能这样写; Max = dp[k^1][i-1]; ans = dp[k][i]; for(int j=i+1; j<=n; j++)///j要从i+1开始是因为:要分成i段至少要有i个数,还有就是下面有个j-1; { Max = max(Max, dp[k^1][j-1]);///Max为前j-1个数分成i-1段中的最大值; dp[k][j] = max(Max + a[j], dp[k][j-1] + a[j]); ///自己成一段(Max);和前面的成一段(dp[i][j-1]); ans = max(dp[k][j], ans); } } printf("%d\n", ans); } return 0; }
以上是关于Max Sum Plus Plus---hdu1024(动态规划求M段的最大和)的主要内容,如果未能解决你的问题,请参考以下文章
C - Max Sum Plus Plus HDU - 1024
Max Sum Plus Plus-HDU 1024(思考:前缀模型优化,延迟更新)
Max Sum Plus Plus-HDU 1024(思考:前缀模型优化,延迟更新)