动态规划
文章平均质量分 68
My_ACM_Dream
生活没有彩排每天都是现场直播
展开
-
以hdu3480为例学会斜率优化&&四边形优化
1、斜率优化,要通过状态转移方程算出现行变化的y1 y2 x1 x2 然后斜率比较,要维护成凸的形状2、第一次接触的就是四边形优化,不过理解不深,其实四边形优化就是记录上一次最有值转移过来的是哪个值,然后下次转移时就直接从这个位置开始,对时间有很大的优化。3、两者比较起来后者比较好写些,第一种方法需要一丁点数学功底(没差),如果四边形熟悉的话,用四边形会更容易写出来。原创 2014-11-13 11:27:45 · 771 阅读 · 0 评论 -
hdu3339(dp+最短路径)
题意是出发点有好多坦克(无限个)为了能阻止原创 2014-11-13 20:06:58 · 782 阅读 · 0 评论 -
Dp_关于最大子矩阵的问题总结
我们知道子一行也是矩阵,只不过是特殊情况,首先来一道题,hdu 1506 高度h[i] 我们定义两个数组,分别为向左扩展能到的最左边的下标,和向右扩展能到的最右边的下标。然后两个数组分别从正方向和反反向扫一遍#include#includeusing namespace std;#define LL long longLL num[100005];LL l[100005原创 2014-11-26 15:51:03 · 599 阅读 · 0 评论 -
hdu4512(最长上升公共子序列变形)
题意就是找出最长的一个序列满足如下条件:1、整个序列对称;2、前半段序列非递减 想想其实可以将序列倒序存储到另一个数组,然后比较两个数组的最长上升子序列。注意一点 j#include#include#include#include#include#include#include#includeusing namespace std;typedef long long原创 2014-11-28 19:51:15 · 863 阅读 · 0 评论 -
hdu1423(最长上升公共子序列)
这题可以作为模板题了。#include#include#include#include#include#include#include#includeusing namespace std;typedef long long lld;#define oo 0x3f3f3f3f#define maxn 505int dp[maxn];int a[maxn], b[m原创 2014-11-28 19:50:13 · 961 阅读 · 0 评论 -
hdu1074(状压DP)
这题本来很简单,代码被我写搓了,字母翘错了一个一直不出结果。#include#include#include#include#include#include#include#includeusing namespace std;typedef long long lld;#define oo 0x3f3f3f3f#define maxn 1<<16int mark[原创 2014-11-27 16:20:30 · 559 阅读 · 0 评论 -
hdu4570(区间dp)
这题很多人是用二维dp其实一维就可以而且时间复杂度只要n^2。我用的是从前往后推结果wa了,大牛的做法是从后往前推。我推导了半天没发现这有什么不同的地方。。。方程很简单 dp[i] = max{ dp[i] , dp[j] + a[i] *(j-i) } (j>=i && j#include#include#include#include#include#include#i原创 2014-11-29 11:02:37 · 572 阅读 · 0 评论 -
hdu1208(记忆优化)
很简单的一道题记忆搜索水过#define _CRT_SECURE_NO_WARNINGS/** this code is made by LinMeiChen* Problem:* Type of Problem:* Thinking:* Feeling:*/#include#include#include#include#include#include#in原创 2014-12-01 11:04:22 · 476 阅读 · 0 评论 -
hdu2412(树形dp+判断解的唯一性)
一群人参加聚会,但是每个人都不想和老板一起参加,问最可以多少人参加。状态方程简单:dp[i][0] += max { dp[j][1] , dp[j][0] }dp[i][1] += dp[i][0];判断唯一性有点难想,加一个状态opt[i][2] 判断是哪个状态转移过来的,然后根据转移过来的状态来判断现在状态。注意了 dp[v][1]==dp[v][0] 是关原创 2014-12-01 12:50:23 · 585 阅读 · 0 评论 -
poj1239(两次Dp)
两次dp求解,题目要求在整个是递增子序列的前提下最后一个元素的值要最小,并且在此前提下第一个的值要最大,不看题解根本想不到怎么做。做法:定义两个dp数组dp_min dp_max 第一个记录某个i点往后能延伸 的点序号即dp[i]-i就是末尾最小数的区间,dp_max则相反记录的是某个i之前的序列即i-dp[i]作为之前的最大数的区间。首先从前往后dp弄出租后一个数的最小值,然后从后往前原创 2014-11-28 17:27:41 · 1475 阅读 · 0 评论 -
zoj 3471 Most Powerful(状压)
题意:给出很多个球,如果a碰撞b,则b消失,并且获得一定的能量Vab,现在给出每两个球碰撞的能量,求能获得的最大的能量。题解:状态:dp[S],S表示已经消失的球的集合。转移方程 dp[ST] = max { dp[S] + val[i][j] , dp[ST] };#include#include#include#include#includeusing names原创 2015-01-06 14:56:08 · 456 阅读 · 0 评论 -
hdu 4336 Card Collector(状态压缩概率dp)
题意:给出n中卡片,并且给出买零食能获得每种卡片的概率,问凑齐n中卡片要买零食的包数的期望。题解:n那么方程的推导如下:状态推导:初始方程: dp[s] = (1-sum(p[i]))*dp[s] + sum(p[j])*dp[s] + sum(p[k])*dp[s|(1<<k)];其中: i=0、1、2、3、4、5......n 1-sum(p[i])表示没有原创 2015-01-25 19:30:42 · 525 阅读 · 0 评论 -
poj 3345 Bribing FIPA(树形dp)
题意:给出n个节点的一个森林,现在要选出至少m个节点,每个节点都有一个价值,如果选了树根对应的子树可以不用花费价值就可以选到,求最小的价值。题解:状态dp[i][j] i为根的树选j个节点的最小价值。整个就一背包,注意初始化就好。#include#include#include#include#include#includeusing namespace std;原创 2014-12-25 18:24:12 · 667 阅读 · 0 评论 -
poj 1837 Balance (暴力dp)
这题不难,挺不错的一题,可以算是暴力dp了,所有情况都遍历一边,状态迭代下去。状态方程:dp[i][j + w[i] * dis[k]] += dp[i - 1][j];//w是重量,dis是距离平衡点的距离枚举重量,然后枚举所放的位置,所有状态都搜索到。/*-------------------------------------------------------原创 2014-12-04 16:41:25 · 515 阅读 · 0 评论 -
hdu 5148 Cities(树形背包)
题意:给出一棵树,现在要选择k个点,要求这个k个点组成的路的平均值(即期望)要最小,路径的综合可以这样计算 :∑Ki=1∑Kj=1dis(vi,vj)题解:题目要求输出的是结果乘以k^2,那么这样就可以要求的其实就是∑Ki=1∑Kj=1dis(vi,vj)这个式子!ok,那么状态就可以设为:dp[i][j] 根节点i选择j个点得到的最小路径和。状态方程:dp原创 2014-12-22 11:08:58 · 646 阅读 · 0 评论 -
用一题来说明dp平行四边优化
poj 1160 题意:给出n个村庄,村庄是一条直线排好的,并且给出每个村庄到直线最左边初始点的距离。现在要建立m个邮局,于是引入一个距离S{各个村庄到最近的邮局的距离和}。那么现在问题来了如何使得这个S的值最小?题解:定义这样的方程 dp[i][j] = min{ dp[i-1][k] + w[k+1][j] } 我们可以看出这个方程满足这样的模型 s[i][j] = s[i][k] +原创 2015-01-27 09:49:27 · 743 阅读 · 0 评论 -
hdu 2993 MAX Average Problem (dp斜率优化)
题意:给出N个正整数,求最大的,长度大于K的某一段的平均值题解:很明显的斜率优化,(sum[i]-sum[j])/(i-j)那么直接队列优化。具体看代码#include#include#include#include#include#include#includeusing namespace std;typedef __int64 lld;#de原创 2015-01-28 11:55:43 · 632 阅读 · 0 评论 -
hdu 3530 Subsequence(dp单调队列优化)
题意:给出n个数的序列,找到这样的区间满足 m题解:用两个队列优化出处理O(nlogn)一个队列存最大值,一个队列存最小值,每次更新,满足条件的入队列,不满足条件的删除队头。#include#include#include#include#include#include#includeusing namespace std;typedef __int64原创 2015-01-28 14:52:56 · 644 阅读 · 0 评论 -
关于dp优化的问题
dp已经是一个很优化的算法,能用很短的时间解决问题能将复杂度降到很低。但是dp也存在优化,这样使dp更加有效。 dp的优化分:单调队列优化、斜率优化、四边形优化。 我觉的单调队列优化是斜率优化的一种特殊形式。下面通过例题来了解dp的优化问题。1.斜率优化:hdu 3507 Print Article 题意:大概题意就是要输出N个数字,分成连续的多段,每一段它的费原创 2015-01-28 14:54:19 · 1021 阅读 · 0 评论 -
hdu 3586 Information Disturbing(树形dp)
题意:给出一棵树,1是根节点,问如果切断边(每个边都有权值)使得总权值小于一个上限up并且小于m,求这样的最小上限up。题解:分析这题 要求上限最小无非就是枚举上限(从1-最大边的权值),对于每个上限都dp一次。直接枚举肯定超时,用二分枚举降低复杂度。#include#include#include#include#includeusing namespace s原创 2014-12-19 01:00:15 · 557 阅读 · 0 评论 -
hdu 1561 The more, The Better(树形dp)
题意:给出一颗树,树的根为0,占领每个节点都会获得一个价值,但是要得到某个子节点的价值必须先要占领这个子节点的直接前驱也就是父亲节点。问得到的最大价值是多少。题目给出最多能占领m个点。题解:树形背包(01)设置状态dp[i][j] 表示以i为根j个节点能得到的最大价值(这里的j可以表示不含根节点有也可以表示含有根节点)在转移时状态应该这样:dp[u][i] = max { d原创 2014-12-20 13:24:30 · 451 阅读 · 0 评论 -
hdu3401_分析降维_队列优化
这题很好,但是就是不会做,队列优化那块#include#include#include#includeusing namespace std;#define oo 0x3f3f3f3f#define maxn 2020#define maxm 2020int dp[maxn][maxm];//到第i天为止拥有的股票数为j时能赚的最大金额int ap[maxn原创 2014-11-13 11:28:16 · 783 阅读 · 0 评论 -
hdu 2829 Lawrence (dp斜率优化||四边形优化)
题意:给出很多一段路线,由n个点组成,每个点有价值,定义某个区间[i,j]上的价值为这个区间没两个点两两相乘的和,现在可以选择m个点炸掉,这样可以分成m+1段,总的价值就是每段价值的和。那么现在问题来了,如何分段使得价值对低呢?题解:这题可以用队列优化和四边形优化,首先讲下队列优化的。队列优化:方程先写出来 设dp[i][j]表示前j点,炸掉i条边的最小值。j>i状原创 2015-01-28 11:21:25 · 791 阅读 · 0 评论 -
hdu 3480 Division(dp四边形优化)
题意:给出n个数,让你把它分成m个集合,不同集合间允许有相同元素,所有集合的并集为全集,使得集合的代价和最小。单个集合的代价为集合中最大值与最小值的差值。题解:这题看过去发现序列可以任意排列,好像不能用dp,很棘手的样子,那么我们可以这样分析一下对于4个数1 4 7 9 我们分成两个集合怎么和分?如果1和7 4和9显然不能最有,1和4 7和9呢?是最优了! 那么这个例子我们看出如果将序原创 2015-01-28 11:32:39 · 656 阅读 · 0 评论 -
hdu 3506 Monkey Party(dp四边形优化)
题意:一群猴子围成圈,每个猴子互相不认识,猴王要给大家互相认识,每个猴子认识别人需要一个时间花费,而且A猴子认识B猴子,则A猴子认识的所有猴子和B猴子认识的所有猴子都能认识,这个代价为所有AB猴子认识的猴子的时间花费和。很明显的环形的区间dp和取石子问题很像。状态方程:dp[i][j]= max{ dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1] }注意一原创 2015-01-28 11:37:52 · 483 阅读 · 0 评论 -
hdu 3516 Tree Construction(四边形优化)
题意:给出n个平面上的点,要求用一棵树将所有点连起来,但是树的枝干只能往x,y的反向走。求边和最小的数。题解:挺难看出来是区间dp的,知道是区间dp就好处理了。状态方程:dp[i][j]=dp[i][k]+dp[k+1][j]+dis(i,j)-(a[i].y-a[k].y)-(a[j].x-a[k+1].x);原创 2015-01-28 11:43:01 · 641 阅读 · 0 评论 -
hdu 3507 Print Article(dp斜率优化)
题意:大概题意就是要输出N个数字,分成连续的多段,每一段它的费用是:这串数字和的平方加上一个常数M。题解:状态方成 dp[i] = dp[j] + M + (sum[i]-sum[j-1])^2这篇博客写的很好#include#include#include#include#include#include#includeusing namesp原创 2015-01-28 12:02:59 · 519 阅读 · 0 评论 -
poj 1947 Rebuilding Roads(树形dp)
题意:给出一棵树,问如何切割边使得剩下的子树的点个数为p,要求切割的变数要最好。题解:这题状态很明显:1、树的根;2、以某个点为根的子树的点的个数。那么状态dp[s][i] 以s为根,节点数为i的子树最小的切割边的个数。那么就有两种决策,要么切割,要么不切割。我们要以s为根的点数和子树的点数,那么对于一个k个点的子树v1.选择切割时:dp[s][i]=dp[s][i]原创 2014-12-20 10:24:57 · 467 阅读 · 0 评论 -
hdu 1011 Starship Troopers(树形dp)
题意:给出一棵树,树上的每个节点都有一个价值,但是要获得这个价值就必须要派出对应多的人数,入口是点1,问得到的最大价值是什么。题解:树形背包(01),状态:dp[i][j] 表示根节点i有j个士兵能获得的最大的价值。 枚举孩子树中节点士兵的个数。#include#include#include#include#includeusing namespace std原创 2014-12-19 13:20:34 · 554 阅读 · 0 评论 -
poj 1739 Tony's Tour(插头dp)
题意:给出地图,起点是(N,1),终点是(N,M),有障碍物,求有多少种方案能从起点到终点。题解:非环形的插头dp,特判一些起点和终点的dp,还要注意一点,从上往下dp的时候因为起点是左下角,所以不存在不建立新插头的方案!不然未走的空格子就被计算成了路径,反而增加累赘的方案数。#include#include#include#include#include#inc原创 2015-01-30 10:21:13 · 578 阅读 · 0 评论 -
poj 3017 Cut the Sequence(dp单调队列优化)
题意:给出n个连续的数字,现在可以将这些数分成很多段(不限制多少段),每段的最大值作为这段的价值,问如何使得总价值小。题解:看了题目一点思路都没有,果断看了神犇的博客,算法特别巧妙,感觉把队列优化用的非常娴熟。思路是这样的,对于每个位置i我定义这样的状态dp[i]表示到i位置位置价值的最小值。那么dp方程 dp[i] = min{ dp[j] , max{ a[j+1],a[j原创 2015-01-29 10:47:30 · 518 阅读 · 0 评论 -
poj3071(概率dp)
这题题意是给出各个队伍的比赛表,哪个队伍赢的概率最高设置状态:dp[i][j] 表示第i轮j存活的概率,那么就要找到前一轮的对手,有个小技巧貌似和二叉树有点像,在同一颗树上。((j >> (i - 1)) ^ 1) == (k >> (i - 1))这个满足就对对手#include#include#include#include#include#include#inc原创 2014-12-05 00:11:24 · 474 阅读 · 0 评论 -
在谈数位dp_用记忆优化解决无法递推的题目
有些数位dp题目真心难用递推,递推貌似很难想,不过搜索相对来讲是比较好设计的,现在可以考虑用搜索,如何搜索?,记忆优化肯定必须的,像dp一样设置状态。两个例题解答如何用记忆优化解决此类问题。hdu 3709 平衡数故名思意,这题要求以某个点为中心点其他各个位到这个为力矩和为0的数。不多说,举个例子 4139 以3为中心,那么左边2*4+1*1 。右边:1*9 刚好左右相等。如何设计原创 2014-12-05 00:38:37 · 666 阅读 · 0 评论 -
poj 1821 Fence(dp单调队列优化)
题意:有一道线性篱笆由N个连续的木板组成。有K个工人,你要叫他们给木板涂色。每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到的钱。要注意的是,工人i可以选择不涂任何木板,否则,他的涂色区域必须是连续的一段,并且S[i]必须包含在内。 最后还有,每块木板只能被涂一次。题解:状态方程总共三个决策dp[i-1原创 2015-01-28 20:57:49 · 498 阅读 · 0 评论 -
ural 1519 Formula 1(插头dp)
题意:给出一张地图,'*'表示障碍物,'.'表示空的,求这个图的哈密顿回路个数。题解:这题和hdu1697相识,但是这题是求单回路,因此要实现单回路必然满足一个特性,最后一个空的也就是最右下角空的格子才将同一个联通分量连在一起。kuangbin的模板非常给力,弥补了一点思维上的缺陷。学习了一点,最小表示法的写法void decode(int code[],int m,l原创 2015-01-29 19:01:50 · 448 阅读 · 0 评论 -
FZU 1977 Pandora adventure (插头dp)
题意:给出一个地图,包含三种格子的地图,'O'表示必须走的点,'*'表示可以走的点,'X'表示不能走到的点。问走完必须走的点的回路个数题解:这题很明显是单回路问题,但是格子有三种,因此就无法确定左后一个非障碍位置,因为我们引入一个变量标记是否某个状态是否已经形成回路。具体做法:每次将状态解压出来时都要让标记变量赋值为状态的最高位(最高位存的就是否是已经有回路的标记),每次在装以前要判断原创 2015-01-29 20:38:18 · 575 阅读 · 0 评论 -
hdu1565(状压dp)
题意好懂不多说。这题有两种解法,一是网络流,二是状压这题用状压做要将行压缩,那么就可以按行dp状态方程:dp[i][j] 第i行状态为j时候的最大值dp[nowst][j] = max(dp[nowst][j], dp[prest][k] + ans[j]);分析会发现可以打表把所有状态离散化,因为很多状态是没用的,不过也可以每次都按照数据范围离散化,一个预处理时,一个原创 2014-12-06 11:55:13 · 611 阅读 · 0 评论 -
hdu4539(状压dp)
题意:给出炮兵的打击范围,和一个矩阵,炮兵之间不能再对方的打击方位内,那么问矩阵最多可以放置多少个炮兵状压,按照行dp,把行压缩,这题不能两行之间dp因为第一行会影响到第三行(炮兵的打击范围可以看出),那么就只能两行两行的dp于是设计这样的状态:dp[i][now][pre] 在第i行时这行的状态为now上行的状态为pre时的最大值。枚举这行的状态,上行的状态,上上行的状态,据处理将所原创 2014-12-06 12:10:08 · 541 阅读 · 0 评论 -
hdu4049(状压dp)
这题说实话,完全没思路,看了题解才明白,题意:有n个m个低点,每个地点都要花钱,每个人去每个地点都有一个兴趣值,如果两个人一起组队就会有福利,多个人就两两结合的福利加在一起。问怎么让这些值综合最大。那么设计这样的状态:dp[i][s] 表示在第i个城市时状态为s的最大值,其实s状态里面包含的就是人的排列组合。next[i][j] :状态i变成第j个的状态是什么 cnt[i] 状态i能变原创 2014-12-06 12:03:42 · 580 阅读 · 0 评论 -
poj2288(状压dp)
这题如果没想限制有三个成环的时候是可以一维转压过的,但是这个条件。。。。所以要设计这样的状态dp[s][i][j]在状态s时现在点是i上个点是j的最大值。枚举上两个点,然后枚举这个点。#include#include#include#include#include#include#include#include#include#includeusing names原创 2014-12-06 12:26:56 · 456 阅读 · 0 评论