NYOJ 742 —— 最大m段和 【区间DP】
2016-05-18 21:37
330 查看
经典区间DP:最大m段和
“最大连续和问题”是最大m段和问题的一个特例,其实是当m=1的一种特殊情况。
OJ题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=742
参考:
http://blog.csdn.net/liufeng_king/article/details/8632430
“最大连续和问题”是最大m段和问题的一个特例,其实是当m=1的一种特殊情况。
OJ题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=742
#include <iostream> #include <cstdio> #define INF 0x3f3f3f3f using namespace std; const int MAXN = 1000000 + 5; typedef long long LL; int a[MAXN]; LL dp[MAXN]; LL maxn[MAXN]; /* dp[i][j] = max(dp[i][j-1]+a[j], max(dp[i-1][k])+a[j]) (i-1 <= k < j) 下面的代码进行了两个很重要的优化:1.滚动数组,空间减少一维 2. 通过动态维护上一行中[i-1,j)的最大值,省去k的一重循环 */ int main () { int T, m, n; scanf("%d", &T); while(T--) { scanf("%d%d", &m, &n); for(int i=1; i<=n; i++) { scanf("%d", &a[i]); } for(int j=0; j<=n; j++) maxn[j] = dp[j] = 0; LL t; for(int i=1; i<=m; i++) { t = -INF; for(int j=0; j<=n; j++) { // 把j个数分成比j还多的段,这是不合法的 if(i>j) dp[j] = -INF; else { dp[j] = max(dp[j-1]+a[j], maxn[j-1]+a[j]); // maxn[j-1]已经被使用完毕,所以可以赋值了 maxn[j-1] = t; // t保存第i行、i~j列的最大dp值, // 但是t不能马上赋值给maxn[j],因为下一次循环到j+1时,要用到原来的maxn[j] t = max(t, dp[j]); } } } printf("%lld\n", t); } return 0; }
参考:
http://blog.csdn.net/liufeng_king/article/details/8632430
相关文章推荐
- NYOJ 1103 —— m划分为n个正整数的个数
- 卡特兰数
- NYOJ 651 —— n划分为2个以上不同正整数的划分个数
- Java集合类的继承关系
- TestNG参数化测试之Excel读取数据
- CSS中的字体背景和盒子模型
- 并查集详解
- NYOJ 571 —— 各种划分数
- NYOJ 90 —— 求正整数n划分为若干个正整数的划分个数
- NYOJ 746 - 正整数n划分为m段,求m段的最大乘积 【区间DP】
- NYOJ 176 、POJ 1664 —— m划分为n个正整数的划分个数
- NYOJ 1077 【博弈+大整数取模】
- 通过指针运算符访问对象成员和构造函数的特点
- NYOJ 23 —— 取石子(一)【博弈】
- SLG时间定价策略浅析
- 最长上升子序列 LIS
- POJ 1141 —— Brackets Sequence
- POJ 3280 —— Cheapest Palindrome
- POJ 3661 —— Running
- 用气发声五大问题的解析