Max Sum Plus Plus (动态规划) HDU1024

摘要:
1#include<stdio.h>2#include<string。h˃ 3#include4usingspacestd;5约束N=1001000;6约束长度INF=0x3f3f3f3f3f3f3f3f;7longlongdp[2][N],最大值;8英寸[N];9intmain(){10intm,n,t;11while{12t=1;///用于滚动数组13 14 dp[0][i]=-INF;15 16扫描;17for{///t=1-t表示在循环中滚动18dp[t][i]=dp[1-t][i-1]+a[i];///对角线值实际上是前n项的总和!!19maxn=dp[1-t][i-1];//不要忘记20 for{21maxn=max;//maxn更新记录max22dp[t][j]=max+a[j];///状态转换步骤23}24}25t=1-t///最后,当i˃m时,++i,t=1-t的影响将变为26maxn=-INF;27/**28注意,在a[j]的情况下,dp[i][j]是前j个数的最大和;29也就是说,dp[m%2][n不一定是最优解,因为在不添加a[n]的情况下,它可能更大;30**/31,32maxn=最大值;33printf;34}35返回0;36}错误代码

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1024

(http://www.fjutacm.com/Problem.jsp?pid=1375)

题意:长度为n的序列里,m段不相关区间的最大和

思路:我们先要确定一个东西,就是状态,这里我用dp[i][j]表示前j个数在取a[j]情况下分i段的最大和;

那么我们为了找规律,可以先来一发Excel,就以样例为例子:

Max Sum Plus Plus (动态规划) HDU1024第1张

然后我们可以发现其实红圈里的8是状态dp[2][6](i=2, j=6),那么我们可以想想这个位置怎么推导,很明显,他可以选择和分i-1块的最大值相加,得到的i块可能是最大,或者他也可以直接和同样分i块的j-1的位置相加,这样就相当于不断开,得到最大。那么也就是他只有两种选择,第一个是dp[i][j-1],第二个是max(dp[i-1][i-1]~dp[i-1][j-1]),也就是dp[i][i~n]只和dp[i-1][i-1~n]这一行的状态有关,和别的无关。那么我们就可以用滚动数组保存;但是如果你找max(dp[i-1][i-1]~dp[i-1][j-1])的时候用的是for查找的话,那就凉凉了,因为那样复杂度就是O(n^3),也就是我们要用一个maxn来记住之前的最大值,然后每次更新记录;具体看代码。

Max Sum Plus Plus (动态规划) HDU1024第2张Max Sum Plus Plus (动态规划) HDU1024第3张
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N= 1001000;
 6 const long long INF=0x3f3f3f3f3f3f3f3f;
 7 long long dp[2][N], maxn;
 8 int a[N];
 9 int main( ){
10     int m, n, t;
11     while(~scanf("%d%d", &m, &n)){
12         t=1;///用来滚动数组
13         for(int i=1; i<=n; ++i)
14             dp[0][i]=-INF;
15         for(int i=1; i<=n; ++i)
16             scanf("%d", &a[i]);
17         for(int i=1; i<=m; ++i, t=1-t){///t=1-t就是在循环滚动
18             dp[t][i]=dp[1-t][i-1]+a[i];///对角线的值其实就是前n项和啦!!
19             maxn=dp[1-t][i-1];///别把这个忘了
20             for(int j=i+1; j<=n; ++j){
21                 maxn=max(maxn, dp[1-t][j-1]);///maxn更新记录max(dp[i-1][i-1]~dp[i-1][j-1])
22                 dp[t][j]=max(dp[t][j-1], maxn)+a[j];///状态的转移步骤
23             }
24         }
25         t=1-t;///最后i>m时的那一个++i, t=1-t的影响要转过来
26         maxn=-INF;
27         /**
28             注意,dp[i][j]是表示前j个数在取a[j]情况下分i段的最大和;
29             也就是dp[m%2][n不一定是最优解,因为可能不加a[n]还更大;
30         **/
31         for(int i=m; i<=n; ++i)
32             maxn=max(maxn, dp[t][i]);
33         printf("%I64d
", maxn);
34     }
35     return 0;
36 }
拙劣的代码

免责声明:文章转载自《Max Sum Plus Plus (动态规划) HDU1024》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#中Dictionary小记linux-创建/使用快照/克隆(类似windows中备份还原)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

数据结构 练习 19-活动选择问题的实现(动态规划 和 贪心)

问题叙述:如下图表示活动的开始和结束时间,s[i],开始时间;f[j]结束时间。现在要进行一些列如下活动,注意每个时间段只能进行一场活动,也就是活动不能同时进行,要求举行的活动次数最多。求调度方法。 老规矩,动态规划,要找出两个问题: 1,子问题的最优解; 2,子问题是什么。 abviously,本问题的最优解为:活动数的次数最多,子问题是:看递推公式...

动态规划解决01背包问题

一、问题描述:有n 个物品,它们有各自的重量和价值,现有给定容量的背包,如何让背包里装入的物品具有最大的价值总和? 二、总体思路:根据动态规划解题步骤(问题抽象化、建立模型、寻找约束条件、判断是否满足最优性原理、找大问题与小问题的递推关系式、填表、寻找解组成)找出01背包问题的最优解以及解组成,然后编写代码实现; 三、动态规划的原理及过程: eg:numb...

斐波那契数列(动态规划)

#include "stdafx.h" #include <iostream> using namespace std; #define MAXSIZE 100 int bofei_bottom(int n) { int f[MAXSIZE]; f[0] = 0; f[1] = 1; for (int i = 2; i <= n;...

luoguP3830 [SHOI2012]随机树 期望概率 + 动态规划 + 结论

题意非常的复杂,考虑转化一下: 每次选择一个叶节点,删除本叶节点(深度为$dep$)的同时,加入两个深度为$dep + 1$的叶节点,重复$n$轮 首先考虑第$1$问,(你看我这种人相信数据绝对是最大的数据,直接$f[i][S]$表示$i$个叶子结点,深度之和为$j$的时候的概率,然后化前缀和化出来...) 对于一个深度为$x$的点,对它操作后,深度增...

贪心整理&amp;amp;一本通1431:钓鱼——题解

题目传送   (其实有一个更正经的题解) 看了许久,发现这题貌似就是一个动态规划啊,但毕竟是贪心题库里的题,还是想想用贪心解吧。 经过(借鉴大佬思路)十分复杂的思考后,终于理解出了这题的贪心思路。该题的难点主要在最后可在任意湖边停住,而且不能往回走,在一个湖钓鱼时的效率还会越来越少。常规的思路看来是不行的了,题目好多动态未知的量,唯有我们更换角度,“化动为...

【动态规划】闫氏dp分析

来源于Acwing yxc的闫氏dp分析讲解,本文为几道经典例题的笔记 目录 53. 最大子序和 120. 三角形最小路径和 91. 解码方法 62. 不同路径 63. 不同路径 II 198. 打家劫舍 72. 编辑距离 53. 最大子序和 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。...