---------动态规划DP---------
TouchDreamer
这个作者很懒,什么都没留下…
展开
-
WOJ Your NP has been charged full(普通dp)
题目分析 现场赛看了这道题并没有写,是因为队友说的题意我理解多了,本来是一个buff三回合之后就没有了,但是我认为只要加上了一个buff那么久一直有这个buff,想dp方程的时候发现有后效性,然后就写不出来了。回来之后重新读题发现一个buff三回合之后消失,那么很明显我们就可以只需知道这回合,上回合以及上上回合选什么buff,然后就可以直接写状态转移方程了,时间复杂度O(n∗33)O(n*3^3原创 2017-04-25 08:33:24 · 389 阅读 · 0 评论 -
HDU 3602 2012(2010 ACM-ICPC Multi-University Training Contest(16)——Host by NUDT)
//dp[i]表示挣i块钱最少需要的座位数//01背包的思想,大家可以这样想,对于每个船我们可选可不选,那么这样//很明显就是一个01背包了。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e4+10;con原创 2016-09-14 10:54:39 · 405 阅读 · 0 评论 -
POJ 3311 Hie with the Pie(状态压缩dp)
题目分析 这道题需要求从0点出发(披萨店)经过其他所有点,并且回到原点的最短距离,因为点数不多最多10个点,很明显是一个TSP问题,并且可以用状态压缩dp进行求解。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int INF = 0原创 2016-09-01 18:36:57 · 232 阅读 · 0 评论 -
POJ 1185 炮兵阵地(经典状态压缩dp)
题目分析 与上一道状态压缩题很想,但是动态规划的状态有不同,这道题跟四周的2行有关,不只是一行了,因此对于这种问题如果还是采用上一中的状态,那么因为跟上2行有关,那么我们会发现这样无法写出状态转移方程,因此需要把上面2个状态合并在一起,这样才能正确的写出状态转移方程。dp[i][j][k]表示在第i行状态为k上一行的状态为j的能放的最大炮兵数量。#include <cstdio>#inclu原创 2016-08-22 15:22:50 · 318 阅读 · 0 评论 -
POJ 2486 Apple Tree(树形dp)
题目大意 这道题的意思就是从根节点开始走k步能得到的最大价值。题目分析 树形dp。首先很容易就可以想到用dp[root][k]表示以root为根的子树中最多走k时所能获得的最多苹果数,接下去我们很习惯地会想到将k步在root的所有子结点中分配,也就是进行一次背包,就可以得出此时状态的最优解了,但是这里还有一个问题,那就是在进行背包的时候,对于某个孩子son走完之后是否回到根结点会对后面是否原创 2016-09-12 21:09:29 · 362 阅读 · 0 评论 -
POJ 3254 Corn Fields(状态压缩dp)
题目分析 状态压缩通常用来处理那些状态很多导致不能容易表达出来,于是需要通过压缩状态进行表示,又利用比如位运算处理一些东西,很容易将结果求出来。我的第一道状态压缩题,注释写的很详细。#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namesp原创 2016-08-22 09:31:46 · 301 阅读 · 0 评论 -
BestCoder Round #86
1001 Price List#include <cstdio>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 100005;typedef long long LL;vector <int> vec;int m原创 2016-08-08 10:47:29 · 285 阅读 · 0 评论 -
HDU 5148 Cities
题目分析 非常好的一道题,这道题同样是求树上的期望问题,也就是每个边被使用的次数乘以 每个边的权值,再除以K*K/2(因为这道题可能会抽到相同的点)因为最后还需要乘以K*K那么这样一化简很明显就是最终得到的结果乘以2就可以了,对于每条边而要,如果左选中n个顶点,右边选中m个顶点,那么很明显,这条边所做的贡献为n*m次。我们对于dp[i][j]表示以i为根节点的子树中选取j个顶点得到的最小的期望值原创 2016-08-05 17:16:39 · 329 阅读 · 0 评论 -
HDU 3586 Information Disturbing
题目分析 这道题wa了不知道多少次,状态转移方程非常好写,但是调bug调了一上午。首先我将程序中的INF设置的过大,导致了加的过程中爆INT,这个潜伏的bug找了好几个小时,真是蠢!!这道题主要思想是利用2分的思想,对于power limit进行2分搜索即可,同时需要注意有可能找不到值,那么需要特判输出-1.最初的时候忘了还有可能有这种情况了,别的就比较简单了,看了一下,这道题时那场多校比赛中可原创 2016-08-05 11:10:10 · 328 阅读 · 0 评论 -
数位dp小结
数位dp如何入门 我最初在网上漫游了一天,终于找到了一个适合自己的学习方式,这里分享给大家。搜数位dp大部分都是记忆化搜索写的,因为这个搜索是反向的,所以一看是看上去真的什么都看不懂,因此我们首先学一下递推版的,这里给出网址,大家可以去看一下写的真的很好,认真看就能看明白初探数位dp,然后看懂了之后就手写代码,通常写hdu2089(不要62)这个入门题,这样我们就可以开始看记忆化搜索了,只是反向原创 2016-07-22 10:29:36 · 246 阅读 · 0 评论 -
HDU 2196 Computer(树形DP)
题目分析 这道题好难想呀!!看了别人的题解继续想还是想不明白,主要是自己的一个点没有过来,题解是先求出每个节点到叶子节点的最长路以及次长路用dp[u][0]和dp[u][1]表示,然后再用一遍dfs求每个节点到经过其父亲节点出发的另一条最长路,状态转移方程是这样的,如果这个节点在其父亲节点的最长路上,那么这个节点经过其父亲节点的最长路我们用dp[son][2]表示,则dp[u][2]=max(d原创 2016-08-04 20:10:52 · 240 阅读 · 0 评论 -
hdu 5783 Divide the Sequence
题目分析 一道水题,本来我以为n*logn的方法会爆炸,但是一看时间给了2500MS,于是果断搞起了,首先我们在边求前缀和的同时进行操作,然后直接将每一个的结果通过二分查找找到给定元素在数列中的位置,然后替换该位置的元素,同时将长度重新设置为此时查找到的长度,因为如果有负数会使前面若干个必须与该负数组合在一起。这样一来求得的长度就是应该求得到最多分成几个子序列的个数。同事需要注意这道题会爆INT原创 2016-08-04 16:12:09 · 195 阅读 · 0 评论 -
HDU 5787 K-wolf Number
题目分析 多校的题目,状态比较好想,但是真的不好写,需要用一些比较巧妙的方法。这道题是数位dp,对于题目要求,我们需要定义的状态时,第一维表示当前处理的数的位数,后面的4维表示当前数字的前4位数,接下来表示当目前为止所有数字位上的数字是否满足K-wolf Number,最后一维肯定还是是否有限制了。对于这道题处理上的小技巧就是:1:当你处理前几位的时候,他们前面是没有数字的,因此我们将他们前面的原创 2016-08-04 13:05:52 · 485 阅读 · 0 评论 -
树形dp基础题
树形dp基础题 该dp的实质就是利用树的性质,儿子节点返回的值可以被父亲节点加以利用以及处理,这样就构成了一种在树结构上的动态规划,简称树形dp。从昨天开始决定刷树形dp专题,刷了4道水题,因此想写一个博客总结一下。POJ 1463 Strategic game 这道题就是在树上的节点添加守卫,很明显我们可以得出以下结论,如果父亲节点不添加守卫,那么儿子节点一定要添加守卫,如果父亲节点添加原创 2016-08-03 14:31:14 · 444 阅读 · 0 评论 -
POJ 1947 Rebuilding roads
POJ 1947 Rebuilding roads 树形dp经典题目,没做过此类题,想了好半天,用到了分组背包的思想,注释写的很清楚,因此就不多讲了。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 155;co原创 2016-08-03 16:12:03 · 369 阅读 · 0 评论 -
POJ 1655 Balancing Act
题目分析 本题就是求每个节点的最小balance,如果有多个节点有相同的balance,那么输出最小的一个。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2e4+5;const int INF = 0x3f3原创 2016-08-03 16:37:27 · 292 阅读 · 0 评论 -
HDU 5456 Matches Puzzle Game(2015 ACM/ICPC Asia Regional Shenyang Online)
题目分析 之前也研究了一段时间的数位dp,但是一直没有见到这种形式的,状态看了好半天都不知道怎么找状态,看了别人的博客,也给看懂了,感觉其实也不是特别难,但是这种dp太不好查错了!!首先将式子化为A = B+C,那么我们需要定义状态,dp有4维,第一维很明显是火柴棍数量,第二维是有没有进位,第三位是B还能不能继续放数字,第四位是C还能不能继续放数字。状态转移方程见代码。#include <cs原创 2016-07-29 16:28:08 · 382 阅读 · 0 评论 -
HDU 1978 How many ways
题目分析 一道简单的动态规划题目,首先状态可能是格子上的每个点了,状态转移方程肯定就是每个点可以到达的每个点了。但是数量很大,因此状态转移的每一步均要取模,同时初始化的时候我搞错了,并不是所有的地方都初始化为0,而是除了起点之外的其他点初始化为0,起点初始化为1.#include <cstdio>#include <cstring>#include <iostream>#include原创 2016-07-07 14:29:10 · 254 阅读 · 0 评论 -
codeforces C. Coloring Trees
题目分析 一道dp的题目,状态很好定义,dp[i][j][k]表示第i个位置为颜色j并且此时树的beauty为k需要的最少的颜料,但是在写状态转移方程的时候我发现自己用了4重循环,我以为这道题会超时,于是没敢下手,但是自己也想不出来优化,于是自己看了一下别人的代码,发现4重循环可以过,于是自己就写了一下,注意状态转移方程,还有状态的初始化问题。#include <cstdio>#includ原创 2016-09-07 11:42:51 · 389 阅读 · 0 评论 -
HDU 3001 Travelling(状态压缩dp)
题目分析 每个点最多走2遍,那么显然是3进制进行压缩,0表示没有走过,1表示走过一次,2表示走过2次,dp[i][j]表示状态为i是到达j点所需要的最小费用,运用我为人人的dp思想,找到现在状态能够到达的状态并更新能够到达的状态,知道满足条件的最小值即可。#include <cmath>#include <cstdio>#include <cstring>#include <iostre原创 2016-09-08 21:24:35 · 216 阅读 · 0 评论 -
HDU How to Type(简单dp)
题目分析 好久没有刷dp,从别人写的dp题中随便拉了一题写了一下,发现不难。状态主要用dp[N][2], dp[i][0]表示处理到第I位并且现在开caps需要的最小次数, dp[i][1]表示处理到第I位并且现在开caps需要的最小步数。状态转移显而易见,看我的代码即可。#include <vector>#include <cstdio>#include <cstring>#inclu原创 2016-10-10 21:17:50 · 314 阅读 · 0 评论 -
大学生程序设计邀请赛(华东师范大学)题解
B 分词 首先建字典树,然后简单dp一下可过,输出有坑!!,因为int没有改成double wa出血。#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAX = 26;const int m原创 2017-05-15 20:56:52 · 546 阅读 · 0 评论 -
hdu 4055 Number String
题目分析 表示自己这个弱菜写这种dp然后并不会,具体过程看注释吧。/*很巧妙的一道题,是别人写的dp总结给出的一道题,这道题消除后效性非常巧妙,dp[i][j]表示长度为i最后一个数字为j的方法数(请注意长度为i的i个数的大小不超过i)这样我们就可以得出状态转移方程了,但是如果对于前一个状态大于等于当前状态最后一个数字的情况是,这个时候我们将这些数字加1,这样消除后效性。我们用sum原创 2017-04-23 16:47:49 · 314 阅读 · 0 评论 -
UVA 11324 The Largest Clique(强连通缩点+记忆化搜索)
题目分析 这道题的意思就是让你找一条路上最长的路径,使得该路上的所有节点均可以达到,注意要么u到达v,或者v到达u。于是我们可以强连通缩点,然后这个图形就转化为一个DAG(有向无环图),然后记忆化搜索一些即可。#include <queue>#include <stack>#include <vector>#include <cstdio>#include <cstring>#inc原创 2017-04-12 21:08:02 · 239 阅读 · 0 评论 -
WOJ 24. Divide by Six
题目分析 一道非常好的dp题,不是很难,但是细节问题很多,比赛的时候瞎搞的,搞了半天没出来,亏我还是队里面写dp的,非常惭愧,比赛的时候一直想着能被6整除的数是一个偶数并且各个数位上的数字相加和mod3等于0,然后写了2个小时,wa了11次,好气呀!!代码上有注释,参考大神解法。#include <cstdio>#include <cstring>#include <iostream>#原创 2017-04-10 20:08:02 · 744 阅读 · 0 评论 -
蓝桥杯 历届试题 最大子阵
题目分析 好久之前就做过,直接将2维转化为类似一维的解法即可。#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn = 505;const int INF = 0x3f3f3f3f;int sum[maxn][maxn];int main(){ int原创 2017-03-11 20:18:47 · 303 阅读 · 0 评论 -
lightOJ 1246 Colorful Board
题目分析 首先我们可以利用坐标来观察,我们发现x+y坐标之和为偶数的颜色可以相同,奇数的也可以相同,所以我们就可以将图分成2部分,然后进行染色。当然这里我们用dp方程打表推出染色所需要用到的各种方法数。dp[i][j]表示用j种颜色染i个格子的方案数,注意这里面j中颜色必须全部用完,因此状态转移方程为dp[i][j] = dp[i-1][j]*j+dp[i-1][j-1]*j;预处理一下即可计算原创 2017-01-12 13:28:15 · 223 阅读 · 0 评论 -
Codeforces Round #360 (Div. 1)
A NP-Hard Problem 一道染色的题目,跟上次写过的一道现场赛的题目很像,简单处理一下即可。#include <cstdio>#include <vector>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1e5+100;int原创 2016-11-20 11:50:11 · 451 阅读 · 0 评论 -
POJ Space Elevator(排序+多重背包)
题目分析 好久没有写背包了,因此找了一个多重背包练一下,因为多重背包是01背包和完全背包的结合,手生,写了有一会!!! 就是给你一下砖块,每一个砖块一个高度,给出数量和这样砖块最多能放的高度。。 这道题因为每个点的限制不一样,所以需要从限制小的先进行dp,因为限制大的可以放在限制小的上面,但是限制小的无法再往大的上面堆,这样就算错了。。#include <cstdio>#incl原创 2016-10-31 16:33:51 · 576 阅读 · 0 评论 -
POJ 2923 Relocation(状态压缩+背包思想)
题目分析 因为是判断2辆车能够运多少次才能把所有的物品给运完,因为物品数不够多,因此可以枚举状态,判断每个状态能否由2辆车给运完,这里面可以用01背包的思想进行判断,然后自己就可以通过状态压缩写出状态转移方程,很明显dp[(1<<n)−1]dp[(1<<n)-1]就是答案。#include <cstdio>#include <cstring>#include <iostream>#inc原创 2016-10-31 12:23:31 · 546 阅读 · 0 评论 -
HDU 5945 Fxx and game(dp+单调队列优化)
题目分析 当初打bestcoder的时候我用广搜写的,并且我知道会超时,但是因为那天脑子太昏了不知道怎么优化,赛后rejudge果然tle。这道题就是用单点队列存放当前位置的前t个位置中最小的那个,代码很懂,也很容易理解,这里就不多说了。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>u原创 2016-11-09 21:08:00 · 321 阅读 · 0 评论 -
2016弱校联盟十一专场10.5 I Increasing or Decreasing(数位dp)
题目分析 这道题就是给你2个数,让你求在这2个数之间单调不减或者单调不增的数的个数,定义状态dp[i][j][k],i表示数的第I位,j表示当前位的前一位数字的多少,k则表达三种意思,k等于0时表示这个序列目前是单调不减的,k等于1表示是单调不增的,k等于2表示目前并没有确定这个序列到底是的单调性,也是就说前几位数是相等的,或者前几位数全为0.这样就可以通过dfs写出状态转移方程,注意不合理的状原创 2016-10-26 20:52:34 · 367 阅读 · 0 评论 -
HDU 4283 You Are the One(区间dp)
题目分析 其实就是出队入队问题,考虑如何出队入队才能让屌丝值最少,无语(写道题还虐单身狗!!)。状态转移方程不好想,具体看代码吧!!#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 105;const int I原创 2016-10-26 15:47:53 · 275 阅读 · 0 评论 -
POJ 3744 Scout YYF I (概率dp+矩阵快速幂,好题)
题目大意 本题很容易求出状态转移方程dp[I]=p∗dp[I−1]+(1−p)∗dp[I−2]dp[I] = p*dp[I-1]+(1-p)*dp[I-2],但是很容易发现这道题的n很大,线性算肯定是不可能,因此利用矩阵快速幂加速无疑是最好的方法。这道题相当于有N个不能过的点,那么我们把不能过的点的概率算出来,用1减去它就可以得到该点的后一个点的dp[i],然后乘以矩阵快速幂得到的结果即可。#原创 2016-10-15 11:29:28 · 294 阅读 · 0 评论 -
POJ 1651 Multiplication Puzzle(区间dp)
题目分析 感觉记忆化搜索好写多了,找到递归边界,一会就写出来了,正着推老是因为要用小区间去推大区间,因此计算顺序很重要,很容易写错,但是记忆化搜索就不怎么用担心这个问题。这道题就是矩阵连乘问题的改版,这道题如果想着一个一个删除处理起来及其不方便,因此还是一个一个往里面加简单,很多dp题都是这样正着推不好推,但是倒着推很容易得到答案。#include <cstdio>#include <cst原创 2016-07-25 16:56:47 · 275 阅读 · 0 评论 -
HDU 4507 吉哥系列故事――恨7不成妻(经典数位dp,好题)
题目分析 让你求与7无关的数的平方和,第一个条件不含7,那么我们在dfs进行深搜的时候遇到这种情况直接continue掉,关于第二个和第三个条件都很简单,只需要在状态中加2维,并且在状态转移中添加上即可。但是这些都不是重点,本题让你求与7无关的数的平方和,刚开始看到求得这个东西内心是崩溃的,但是你要想到数位dp是按位进行求解的,因此肯定是一位一位去求,并且将深度较大的节点的值传给深度较小的递归求原创 2016-10-14 15:39:06 · 476 阅读 · 0 评论 -
HDU 5898 odd-even number(2016 ACM/ICPC Asia Regional Shenyang Online)
题目分析 数位dp,记录下当前位置的奇数个数和偶数个数,遇到偶数,判断奇数是否合法,并且将奇数更新为0,同理遇到奇数也一样。注意前导0的判断。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;LL dp[2原创 2016-09-26 16:28:44 · 345 阅读 · 0 评论 -
HDU 5900 QSC and Master(2016 ACM/ICPC Asia Regional Shenyang Online)
吐槽 2016沈阳网络赛最水的题目,自己写了2个小时无果,最终放弃,作为搞dp的我深感自责,自己区间dp确实也没有做过几道题,当时只是模模糊糊写出了状态转移方程,假如I和k匹配,那么一定要保证i+1到k+1中的所有数也需要匹配,就这一点一直没有好的想法,加上自己网络赛的气氛比较沉重,最后无果!!!,因此这道题很显然就是需要特殊判断一下,别的没有什么大问题。#include <cstdio>#原创 2016-09-26 10:24:48 · 345 阅读 · 0 评论 -
HDU 1078 FatMouse and Cheese
题目分析 这道题跟poj上面的滑雪是一样的题目,但是这道题改变的地方有,每一次可以移动k步,而不是一步,很明显多加一重循环就可以了,同时那道题求得是递减的长度,这道题求得是递增得到的最大数量的奶酪。直接记忆化搜索就可以了。#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using nam原创 2016-07-07 11:06:44 · 233 阅读 · 0 评论 -
HDU 1506 Largest Rectangle in a Histogram
题目分析 首先需要找到最左边以及最右边比h[i]大的位置,这样结果就很容易算出来,ans = h[i]*(r[i]-l[i]+1);但是求l[i]以及r[i]如果不进行优化的话会直接超时,因此我们可以利用前面所求的l[0….i-1]来更快的得到l[i],本题的难点也在这。自己拿手对着代码推一遍你就会理解了,详细的请看代码。#include <cstdio>#include <cstring>原创 2016-06-19 17:37:09 · 227 阅读 · 0 评论