HDU 1024 Max Sum Plus Plus --- dp+滚动数组
题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交。
解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值,其中第i个子序列包括a[j],
则max(dp[m][k]),m<=k<=n 即为所求的结果
<2>初始状态: dp[i][0] = 0, dp[0][j] = 0;
<3>状态转移:
决策:a[j]自己成为一个子段,还是接在前面一个子段的后面
方程:
a[j]直接接在前面的子段之后, 则dp[i][j] = dp[i][j-1] + a[j];
a[j]自己作为一个子段,先求得前面k个数组成的最大i-1段子段和,再加上a[j],
即dp[i][j] = max(dp[i-1][k]) + a[j],其中 1=<k<=j-1;
即 dp[i][j] = max(dp[i][j-1] + a[j], max(dp[i-1][k]) + a[j]), 其中k>=1&&k<=j-1;
<4>空间复杂度优化:
本题由于n可以达到100 0000,开不出dp[n][n],因此需要利用滚动数组优化空间。
从状态转移方程中可以看到,当前行位置为j的状态dp[i][j]的更新只需要利用到上一行的前j-1个状态最大值
因此最多只需要两行数组
<5>时间复杂度优化:
每次更新dp[i][j]时,都需要找到上一行的前j-1个状态的最大值,这样复杂会达到O(n^3);
其实,可以每次更新当前行的dp[i][j]后,将其相应的前j个数的最大值保存在pre[j]中,
这样,在下次更新下一行时可以可以直接使用当前行保存的pre[j],而不用再搜索,
因此,时间复杂度可以优化到O(n^2)
/* HDU 1024 Max Sum Plus Plus --- dp+滚动数组 */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ;
int dp[maxn], pre[maxn]; //pre[j] = dp[i-1][
int a[maxn];
int m, n; int main()
{
#ifdef _LOCAL
freopen("D:\\input.txt", "r", stdin);
#endif while (scanf("%d%d", &m, &n) == ){
//输入
for (int i = ; i <= n; ++i){
scanf("%d", a + i);
}//for(i)
int MAX; //定义第一行的第一个状态的前驱,此时的i相当于1,dp[1][0]
dp[] = ;
//初始化pre数组全为0,此时pre数组所对应的行应该为0,
memset(pre, , sizeof pre);
for (int i = ; i <= m; ++i){
//内循环做的是更新当前第i行的状态, 注意 j >= i 才有意义 MAX = -10e8; //将MAX初始化为一个很小的数
for (int j = i; j <= n; ++j){
/*
状态转移方程里的pre[j]保存的是上一行的前j个数的最大值,
即pre[j] = max(dp[i-1][k]), 1<=k<=j 若a[j]直接属于第i段, 则 dp[i][j] = dp[i][j-1] + a[j]
在这里就是 dp[j] = dp[j-1]+a[j]
若a[j]自成一段,则需要找出 dp[i-1][k]的最大值,其中 1<=k<=j-1,即pre[j-1]
*/ dp[j] = max(dp[j - ], pre[j - ]) + a[j];
/*
下面pre数组和上面有细微的区别
上面的pre[j-1]保存是上一行(第i-1行)的前j-1个数的最小值
而下面的pre[j-1]更新后保存的是当前行的前j-1个数的最大值,
更新后是用于下一行的dp的更新,即i要+1后才会用到
另注意MAX是上次内循环所更新的值,即当前行(i)的前j-1个数的最大值
*/
pre[j - ] = MAX;//更新pre,保存当前行的前j-1个数的最大值,为下一行的dp更新做准备
if (dp[j] > MAX){
//这里的MAX记录的是当前行的前j位的最大值
//到下一个内循环j会+1,这就是为什么MAX可以在上面用于更新pre[j-1]
MAX = dp[j]; //MAX记录当前行的前j位的最大值
}
}
}//for(i)
printf("%d\n", MAX); } return ;
}
HDU 1024 Max Sum Plus Plus --- dp+滚动数组的更多相关文章
- HDU1024 Max Sum Plus Plus —— DP + 滚动数组
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1024 Max Sum Plus Plus Time Limit: 2000/1000 MS ...
- HDU 1024 A - Max Sum Plus Plus DP + 滚动数组
http://acm.hdu.edu.cn/showproblem.php?pid=1024 刚开始的时候没看懂题目,以为一定要把那n个数字分成m对,然后求m对中和值最大的那对 但是不是,题目说的只是 ...
- hdu 1024 Max Sum Plus Plus DP
Max Sum Plus Plus Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php ...
- HUD 1024 Max Sum Plus Plus (滚动数组)
题意:从一个序列中选出分成不交叉的m段 的最大和 解析 : 题目中 1 <= n <=1000000 所以二维数组是不能用了 所以 要想到简化为一维 dp[i][j]表示以i结尾的前i个 ...
- hdu Max Sum Plus Plus(dp+滚动数组)
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 m为段,要深刻理解题意,并没有说是段与段要连接. 题解链接:http://blog.csdn.n ...
- HDU 1024 Max Sum Plus Plus (动态规划)
HDU 1024 Max Sum Plus Plus (动态规划) Description Now I think you have got an AC in Ignatius.L's "M ...
- HDU 1024 Max Sum Plus Plus(m个子段的最大子段和)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1024 Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/ ...
- HDU 5119 Happy Matt Friends (背包DP + 滚动数组)
题目链接:HDU 5119 Problem Description Matt has N friends. They are playing a game together. Each of Matt ...
- HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意: 给定序列,给定m,求m个子段的最大和. 分析: 设dp[i][j]为以第j个元素结尾的 ...
随机推荐
- WP8.1 Study5:Data binding数据绑定
一.数据绑定 最简单的编程UI控件的方法是写自己的数据来获取和设置控件的属性,e.g. , textBox1.Text = "Hello, world"; 但在复杂的应用程序,这样 ...
- HDU 3341 状态压缩DP+AC自动机
题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...
- JVM-对象的存活与死亡
当Java虚拟机进行垃圾收集的时候,那么它必须要先判断对象,是否还存活,如果存活就不能对它进行回收.所以判断一个对象是否存活是Java虚拟机必须要实现的. 1.对象是否存活 1)引用计数器:给对象添加 ...
- 直接拿来用的10个PHP代码片段
PHP是一种HTML内嵌式的语言,是一种在服务器端执行的嵌入HTML文档的脚本语言.PHP拥有数以百计的基本功能,支持上千种扩展.这些功能都被很好的加载在PHP站点上,但内置的库有各种各样的命名.在P ...
- JavaScript:变量对象(Variable Object)
引言:在使用JavaScript编程的时候,避免不了声明函数和变量,但是我们很少知道解释器是如何并且在什么地方找到这些函数和变量的,我们在引用这些对象的时候究竟发生了什么? 对ECMAScript程序 ...
- (转)UIApplication sharedApplication详细解释-IOS
iPhone应用程序是由主函数main启动,它负责调用UIApplicationMain函数,该函数的形式如下所示: int UIApplicationMain ( int argc, char *a ...
- Mvc5 Html.EditorFor
如果对缺省的样子不满意, 可以有模板,寻寻觅觅,摸索出 在Views\Shared\EditorTemplates下创建String.cshtml 必须的是EditorTemplates文件夹 @{ ...
- BroadcastReceiver的最简单用法
android系统下的广播: 电池电量低.电池充电完成.短信到来了.程序安装卸载.sd卡卸载安装 等 BrocastReceiverDemo.java public class BrocastRece ...
- hdu 2098
ps:TLE一次....因为判断素数的时候没开方...作死.. 代码: #include "stdio.h" #include "math.h" int inp ...
- 【LeetCode OJ】Insertion Sort List
Problem: Sort a linked list using insertion sort. The node of the linked list is defined as: /** * D ...