动态规划
文章平均质量分 76
ok_again
起步级菜鸟
展开
-
hdu 5834 Magic boy Bi Luo with his excited tree
首先,如果要求的是以1作为开始位置的话,很容易想到一个dp[u][2],其中dp[u][0]表示以u节点为开始位子的子树最后回到u节点获得最大值,dp[u][1]表示不回来。转移就显而易见了。然后,考虑如果u节点结果已经计算出,怎么计算他的儿子节点v的答案。那么,也容易想到转移ans[v]=max(dp[v][1], dp2[u][!v][0] + dp[v][1] - 2 * c, dp原创 2016-08-14 23:01:10 · 932 阅读 · 0 评论 -
ZOJ 2319 Beautiful People
LIS。先按S降序升序再按B降序排序(如果B不按降序排序的话就会覆盖掉正解),然后再对B用O(nlog(n))的LIS求解就可以了。用d数组标记每个元素在上升序列中的位置,然后根据d倒着找id就可以了。#include#include#include#include#include#include#include#include#include#include#incl原创 2013-10-29 17:27:23 · 1231 阅读 · 0 评论 -
HDU 4283 You Are the One
区间dp,如果一个人入栈的话,那到这个人出栈的那一段上台的人肯定是原本位置和当前位置之间的那些人,所以这一个区间可以考虑为一种情况,所以就把问题弄成把一个大区间分解,找出满足题意的最小值了,于是就成为了区间dp问题了dp[l][r]表示只有这个区间的值时可以得到的最小值,考虑区间(l,r) 则一种情况是把区间继续往下分,于是dp[l,r] = min(dp[l,r], dp[l][i] + dp[原创 2013-09-09 18:40:16 · 891 阅读 · 0 评论 -
hdu 4487 Maximum Random Walk
概率DP。给你向左和向右走的概率,要求的是走n步到达最远的位置的期望。首先想到的是直接求期望,但是我们会发现,求期望的话没法定义DP的意义,而且我们发现每一种走法最后一定最远距离一定是0-n,这样的话我们可以递推出到达每个点的概率,然后发现二维的话是不可以求出答案的,因为二维我们没办法计算最远距离。于是只好加上一维表示当前最远距离。于是就有了递推式。dp[ i ][ j ][ k ] 表示第 i原创 2013-10-18 10:45:59 · 1512 阅读 · 0 评论 -
SPOJ AMR12E Dyslexic Gollum
AC自动机+DP。题目要求是生成一个长度为n的 0-1 串,其中最长回文子串的长度小于 k ( 1 <= k <= 10)。原创 2013-10-16 18:08:31 · 1285 阅读 · 0 评论 -
poj 4019 Immediate Delivery
dp。可以用spfa,也可以暴力一些的dp,我这里用的是暴力一些的dp。。。容易写一些。这道题的关键是输出路径,算是路径输出的好题吧!首先我们用dp[ i ][ j ]表示当前状态为 i (将点压缩) 时,最后访问的点为 j 时的最短距离。然后先Floyd 预处理一下每两对点之间的距离,然后暴力枚举 状态,然后递推就可以了。输出路径比较恶心,需要将Floyd处理后的两点之间路径还原为原图上的路径,原创 2013-10-15 17:43:38 · 1323 阅读 · 1 评论 -
hdu 4455 Substrings
dp。dp[ i ]表示长度为 i 的答案。则我们可以发现有dp[ i ] 和 dp[ i - 1 ],我们看各自的第一种满足的情况有{a1,a2,a3.......ai}, {a1,a2,a3.......a[i - 1]}则可以发现dp[ i ],和dp[i - 1]是存在递推关系的。#include#include#include#include#include#defin原创 2013-09-27 19:57:41 · 993 阅读 · 0 评论 -
hdu 4753 Fishhead’s Little Game
状态压缩dp解博弈问题(记忆化搜索)。比赛的时候最后才开始做这道题,而且当时不知道为什么一直犯一些很2B的问题,导致没能ac,晚上看了看原先的代码,改了一下就MLE了。。。我原先是开的dp[1 << 24] 的记忆化数组,果断超内存了,然后仔细看了一下题目,发现题目中的n >= 12,也就是说用到的状态不超过2^12个,于是把满足情况的状态hash到2^12以内的数组就可以了。原创 2013-09-22 00:48:29 · 1521 阅读 · 0 评论 -
hdu 4427 Math Magic
一个长了一张数学脸的dp!!dp[ i ][ s ][ t ] 表示第 i 个数,sum为 s ,lcm下标为 t 时的个数。显然,一个数的因子的lcm还是这个数的因子,所以我们的第三维用因子下标代替lcm,可以有效的减少枚举量。原创 2013-09-24 22:14:58 · 1212 阅读 · 0 评论 -
hdu 2825 Wireless Password
AC自动机+DP。第一道自己做出来的AC+DP。。自动机部分相信大家已经很熟悉了,DP那部分其实就是在自动机上跑出一个新串即可,用val数组标记自动机中到达每个节点所包含的单词种类(用状态压缩)。因为范围很小,所以直接暴力dp就可以了,注意用滚动数组实现DP,不然会超时。。#include #include #include #include #include #include原创 2013-10-10 13:59:59 · 1687 阅读 · 1 评论 -
hdu 2457 DNA repair
AC自动机+DP。按着自动机跑,(其实是生成新的满足题目要求的串,然后找改变最少的。)但是不能跑到是单词的地方,如果跑到单词的话那么说明改变后的串含有病毒了,不满足题意。然后就是应该怎么跑的问题了,现在我们从自动机的根节点开始跑,如果跑到下一个节点和当前串的字母不一样的话,那么当前位置生成的串是和原串在该位置是有差异的,dp+1,否者的话dp不变。所以dp[ i ][ j ]表示的是匹配到当前匹配原创 2013-10-10 11:38:28 · 1499 阅读 · 0 评论 -
hdu 4734 F(x)
数位dp,数位dp类的题目,一定要想清楚再写代码。如果没想清楚的话最好不要写。。。不然越写越乱。 dp[ i ][ j ][ k ] 表示为 小于 (j + 1) * 1e i 的所有 x 所组成f (x)等于k 的x的个数。则有状态转移方程: dp[ i ][0 ][ k ] = dp[ i - 1 ][ 9 ][ k ]; d原创 2013-09-23 20:55:24 · 993 阅读 · 0 评论 -
hdu 4126 Genghis Khan the Conqueror
prim + 树形dp,首先用prim预处理,建出最小生成树,然后,如果更新的不是最小生成树上的边,那么新图中的最小生成树即为原来的最小生成树。如果更新的为最小生成树上的边,则我们需要考虑两个方面: 1、将原来最小生成树的边,换成新边的新生成树的长度。 2、把原来的边删除,原图上从新生成最小生成树。第一个问题比较容易解决,直接用原生成树,算就可以。仔细想一下第二原创 2013-09-23 13:29:40 · 1859 阅读 · 0 评论 -
SGU 534 Computer Network
树形dp。好题!题目要求的是用最小的价值使得树直径变短,虽然,完全不是自己想出来的,但是为了纪念一下这道题,就发一篇题解吧。。。因为网上的题解实在是太少了。。。我找了很久很久才找到了一个大牛的博客里面讲了这道题。 附大牛dxhisboy博客:http://dxhisboy.blog.163.com/blog/static/2096440982011101595210606原创 2013-10-22 18:28:54 · 1306 阅读 · 0 评论 -
UVALive 4857 Halloween Costumes
区间dp。对于最左边的点: 1、在该点穿的衣服只有该点用的到,即穿上就脱下。所以dp[ l ][ r ] = min(dp[ l + 1][ r ] + 1, dp[ l ][ r ])。 2、衣服仍保留。这一步需要明确只有后面用到这件衣服才会选择保留。假如当前位置是i,j 位置和当前位置衣服相同。就可以考虑当前衣服一直穿到了 j 位置。因为在此期间该衣服可能还会被原创 2013-10-31 10:31:18 · 1114 阅读 · 0 评论 -
hdu 5136 Yue Fei's Battle
当时做的时候整个人都已经糊掉了,搞了半天没过掉。其实很简单,dp[i]表示深度i的二叉树有多少种情况。然后分奇偶讨论下k就可以了。//#pragma comment(linker, "/STACK:1024000000,1024000000")#include#include#include#include#include#include#include#include#in原创 2015-04-16 15:43:44 · 701 阅读 · 0 评论 -
UVALive 4394 String painter
很好的一个区间dp,长知识了。。。原创 2013-08-22 14:52:08 · 1215 阅读 · 0 评论 -
poj 1742 Coins (背包)
这道题直接多重背包算的话会超时,但是按完全背包dp但在计算过程中用一个标记数组标记一下加了几次该coin 得到该值。这样可以使时间复杂度降低很多。。。#include#include#include#include#includeusing namespace std;const int N = 111;const int M = 111111;int a[N],原创 2013-05-27 15:17:50 · 822 阅读 · 0 评论 -
HDU 3757 Evacuation Plan
dp。由于内存限制非常严格,所以要用滚动数组,而且本来输出location的时候我也是用的二维int数组,然后就超内存了,只好改成了bool类型了。对于每个队,要么是和前一个队去同一个地方,要么去前一个队的后一个地方,只有这样才能保证最后总花费最小,这也算是贪心了一下吧,然后就很容得出状态转移方程了: dp[i][j] = min(dp[i - 1][j - 1] + abs(a原创 2013-11-22 20:38:16 · 1259 阅读 · 0 评论 -
zoj 3734 LIKE vs CANDLE
树形dp。因为最终答案要求的是差值,所以对于每个节点我们只需要考虑差值即可,dp[u][0]表示u节点以下(含u)中like的val比candle的val大的最大值,dp[u][1]表示candle的val值比like大的最大值。所以,对于每个节点我们就可以对于每个子树v: dp[u][0] += dp[v][0];dp[u][1] += dp[v][1]; 但是原创 2013-11-25 22:48:21 · 1648 阅读 · 0 评论 -
hdu 4778 Gems Fight!
dp+博弈。首先我们发现,背包竟然只有21个。。。这样的话我们就可以用状态压缩表示当前状态都还剩下哪些背包了。然后对于当前状态,有两个转移方向: 1、枚举背包,如果当前背包对cooker有影响的话,我们就会得到魔法石tmp个,这样的话下一步就还是当前人拿,这样的话就是dp[sta] = max(tmp + dp[sta ^ (1 2、如果当前背包对co原创 2013-11-09 17:43:55 · 2955 阅读 · 4 评论 -
URAL 1900 Brainwashing Device
dp。注意值是非负数。。所以会出现所有数据都是0的情况,所以dp初值要赋成-1。这道题的思想挺巧妙的,首先我们分析一下题目,其实可以发现,如果边 i -i+1 被选中,那么i点以前的点对i+1点以后的所以点就都没有影响了。因为如果存在边c[ i ][ j ] > 0 那么肯定在边i - i+1时就已经happy了。所以对于以后的情况就不用考虑了。这样的话就可以把原题分解成一些子区间。所以我们可以用原创 2013-11-08 19:21:06 · 1742 阅读 · 0 评论 -
Uva 12660 - Ears Cutting
计算几何+dp。要求的是将一个多边形分解成三角形最小的切割长度。先预处理出两点是否可以连线(连线在多边形内),然后再dp。dp[ l ][ r ]表示第l个点到第r个点都切割成三角形需要的最小值。于是就可以写出转移方程。 dp[ l ][ r ] = min(d[ i ][ l ] + d[ i ][ r ] + dp[ l ][ i ] + dp[ i ][ r ]原创 2013-11-07 20:55:15 · 1092 阅读 · 0 评论 -
UVALive 6039 Let's Go Green
树形dp。反向思维,考虑最多的情况,即所有边权和,减去没必要的,就是答案了。。。 在做减法的时候,对于一个点: 1、当存在有一条边(tmp)的权值大于通过该点所有边权值和(sum)的一半时,显然,对于除了tmp的其他边,都可以让通过tmp的自行车走这些边。所以ans -= sum-tamp。 2、当不存在上述情况时,我们就可以把通过这个点的边分成两半,这样的话对于该点就原创 2013-11-01 19:21:23 · 1444 阅读 · 0 评论 -
UVALive 6042 Bee Tower
dp。只需要对于每个最高点,从左边递推一遍,再从右边递推一遍。找最小的花费就可以了。#include#include#include#include#include#include#define LL long long#define CLR(a, b) memset(a, b, sizeof(a))using namespace std;const int N = 1原创 2013-11-02 14:03:48 · 1165 阅读 · 0 评论 -
hdu 4705 Y
树形dp。直接搞树形dp,然后统计一下个数就可以了。对于一个节点,假如以这个节点为根节点的话,那么在任意三个不同子树上的点都可以算是满足题意的一种解。那么,我们用sum表示该子树之前的所有在两个子树上的点对的个数,当前子树的个数为now,那么就有ans += sum * now;lxt表示该子树之前的节点数,那么sum可以更新为,sum += lxt * now。 这样的话,最后ans就是答案了原创 2013-11-15 11:19:17 · 1227 阅读 · 0 评论 -
ZOJ2317 Nice Patterns Strike Back
By watashi 。import java.math.*;import java.util.*;public class Main { class Matrix implements Cloneable { public long[][] a; public Matrix() { a = new long[d][d]; } public M转载 2013-10-31 13:45:58 · 1495 阅读 · 0 评论 -
hdu 4758 Walk Through Squares
AC自动机+DP。想了很久都没想出来。。。据说是一道很模板的自动机dp。。。原来自动机还可以这么跑啊。。。我们先用两个字符串建自动机,然后就是建一个满足能够从左上角到右下角的新串,这样我们就可以直接从自动机中跑出一个满足题意的串就可以了,(貌似需要建新串的AC+DP都需要这么搞啊!)可以利用chd数组去递推得到状态的种数。这里我们用dp[ i ][ j ][ k ][ s ]表示当字符的位置为原创 2013-10-08 19:46:30 · 1108 阅读 · 0 评论 -
hdu 4756 Install Air Conditioning
Prim + 树形dp,南京网络赛的题目。这道题和12年福州现场赛的一道题很类似(hdu 4126 Genghis Khan the Conqueror),替换最小生成树上每一条边(与 0 点相连的边除外),然后分别求次小生成树,求生成树中的最大值。可以先prim求出最小生成树,再用dp求把边u - v 边删去,两颗子树的最短距离,分别替换求值就可以了。#include#incl原创 2013-09-23 15:38:38 · 1708 阅读 · 0 评论 -
HDU 4122 Alice's mooncake shop
单调队列,裸的!!坑死了,说好的“All the orders are sorted by the time in increasing order. 呢,我就当成严格上升的序列了,于是就各种错。测试数据是有重复元素的!!!//#pragma comment(linker, "/STACK:1024000000,1024000000")#include#include#include原创 2013-09-20 19:08:41 · 1067 阅读 · 0 评论 -
HDU 4291 A Short problem
通过矩阵快速幂找循环节,注意要每一层都要找一次循环节。。。发个题解仅供大家对拍。。。#include#include#include#includeusing namespace std;#define MAXN 2#define LL long longLL MOD;struct Matrix{ LL data[MAXN][MAXN]; void init(原创 2013-09-06 18:13:14 · 1060 阅读 · 0 评论 -
HDU 4293 Groups
模型挺好的dp题,其实这道题就是建一个模型然后就很容易想到递推过程了,我们可以把每个人的描述,存到数组a中,a[l][r]表示左边有l个,到第r个这个人所在一层停止。。。然后就可以写出转移状态方程了。注意如果dp[i]>dp[j] && i #include#include#include#include#include#define LL long long#define CLR原创 2013-09-06 17:49:59 · 981 阅读 · 0 评论 -
HDU 4433 locker
很暴力的一个dp,dp[i][j][k] 表示的是第i位时,前i-1位都匹配后,当由前面的状态推出第i位+j,i+1位+k时最少用多少步。注意up和down要分开算。。#include#include#include#include#include#define LL long long#define CLR(a, b) memset(a, b, sizeof(a))using原创 2013-09-06 11:18:27 · 1129 阅读 · 0 评论 -
UVALive 3530 Martian Mining
Rujia Liu说这道题模型简单。。。但是我做了很久才做出来。。。@_@。。 先预处理矩阵,a矿表示为横向和的形式,b矿表示为纵向和的形式。 dp[i][j][k] : k = 0 表示i, j块为横向时表示的横向大于等于i,纵向大于j的所有块的选择和的最大值。k = 1 表示i, j块为横向时表示的横向大于i,纵向大于等于j的所有块的选择和的最大值。#include#原创 2013-08-18 15:32:05 · 983 阅读 · 0 评论 -
poj 1185 炮兵阵地
经典状态压缩dp,明显是压缩列,但是需要考虑前两行所有职能开3维矩阵了,可以先把满足的情况存入vector中,这样可以减少枚举状态。。。。#include#include#include#include#include#include#define LL long long#define CLR(a, b) memset(a, b, sizeof(a))#define SL(原创 2013-08-29 10:22:14 · 835 阅读 · 0 评论 -
UVALive 4727 Jump
大白书习题,为约瑟夫变形问题。给你n个数组成一个环,从第k个元素开始删除,每隔k个元素删一个。。。 经典的约瑟夫问题是求最后一个剩余的元素,可由递推公式 f[1] = 0, f[n] = (f[n - 1] + k) % n(下标0~~n-1,公式证明请见百度百科)得到。该题是让输出最后三个被删除的元素,其实该递推公式表示意思是:最后删除的那个元素时,有且仅有那个元素,然后一层一层递原创 2013-08-18 12:38:25 · 1258 阅读 · 0 评论 -
UVALive 4256 Salesmen
树形dp入门题。找出给出路径最相近路径,输出路径上不同节点个数。其实就是dfs + 记忆化。 也可用递推得出答案,个人觉得记忆化的方法容易理解和方便书写。#include#include#include#include#includeusing namespace std;const int N = 111;const int M = 11111;原创 2013-08-18 13:03:51 · 960 阅读 · 0 评论 -
UVALive 4015 Caves
树形dp,自己想了很久很久都没想起来怎么做。。。汗,真笨啊。只好看了一下别人的思路,挺巧妙的,原来树形dp的第三维这么能这么表示,看来以后要让自己的思维更加发散些才能做的出来这种题了。dp[u][l][f] ,u表示当前节点,l表示该节点能到达l个节点所走路程的最小值。当f = 1时表示不用回到当前点,f = 0表示必须回到当前点。则状态转移方程可以表示为: dp[u][j][0]原创 2013-08-27 18:14:44 · 1138 阅读 · 0 评论 -
UVALive 4327 Parade(hdu 2490 Parade)
单调队列优化的dp,要用到两层单调队列。。做了很久很久。。。原来用long long 运算要比用int慢上很多很多,就是因为我用的longlong 一直超时,改成int就ac了,真是无语啊。。。这题模型挺容易想的,但是数据量超大,肯定不能正常的递推,仔细想想可以发现,其实每一次递推不必用前一层所有满足情况的值去找到该层的最大值,可以用单调队列维护满足条件区间的最大值,这样就可以在O(1)的时间下获原创 2013-08-23 10:20:01 · 1539 阅读 · 0 评论 -
UVALive 2038 Strategic game
树形dp,求最少放多少个士兵,使得每条边都被每条路都可以被士兵侦查到。即选择最少的点,使得树上任意一条边至少有一个顶点被选中。dp[i][j], 当j = 0时,表示当点i不放士兵时最少放了多少个士兵,j = 1时,表示放士兵时最少有多少个。注意:两个相邻点都可以选择放士兵。#include#include#include#include#include#include#inclu原创 2013-08-20 16:10:20 · 991 阅读 · 0 评论