=====动态规划=====
文章平均质量分 62
林伏案
妖蛾子良多的范老爷
展开
-
hdu1160(dp的lis模型)
/*translation: 给定一组老鼠的体重和速度,求出这样的一组老鼠数列,使得老鼠的体重在增加,速度在减少。solution: dp,lis 首先按照重量对老鼠进行排序,然后按照普通lis做法即可。note: 1.题目题意有问题,说是求sebsequence,但是按照子序列的定义来看,求出来的根本不是子序列。比如样例第9个数据组 竟然在第7个数据组之前!!而子序列的要求是原创 2017-04-02 09:59:13 · 450 阅读 · 0 评论 -
uva1630(dp记忆化搜索)
/*translation: 将一串字符串折叠成一串尽量短的字符串solution: 记忆化搜索dp 可以看出一串字符串有3种情况: 1.字符串本身就已经是最简短 2.可以折叠成某一个更短的字符串 3.只有一部分能够折叠成更短的字符串,这时需要分成两部分来求解,需要遍历来确定拆分的位置 根据以上3种情况即可编码note: * 字符串折叠类型的题可以考虑区间dp和记忆化搜索原创 2017-01-14 21:32:56 · 822 阅读 · 0 评论 -
poj3254(常见的二维状压dp)
/*translation: 给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多少种放法solution: 状态压缩dp 每次枚举时候判断是否符合当前草地的情况,再判断是否跟前面的一行兼容。note: * 将所有合法状态预先处理存进一个数组里面即可提高速度 # 一开始check(i, s)WA了好多次,后来发现应该是ch原创 2017-01-01 01:19:02 · 295 阅读 · 0 评论 -
poj2441(状压dp)
/*translation: 要给n头牛分配m个牛舍,每头牛有自己喜爱的若干牛舍。问总共有多少种分配方法?solution: 状态压缩dp即可。dp[s]表示到状态s的方案数目note: * 注意用__builtin_popcount(s)函数来判断1的个数是否满足转移的条件。date: 2016.12.31-----跨年题。希望17年赛季能够拿个牌子!!*/#include原创 2016-12-31 21:52:04 · 332 阅读 · 0 评论 -
poj2686(TSP)
/*translation: 一张图由n个点构成,并且若干个点之间由双向边连成。有若干票,每次走完一个边花费一张票 花费时间是边的长度 / 票的权重。求从指定起点到终点所用的最短时间。solution: 状压dp 首先观察数据,发现n比较小,很容易看出对n进行状态压缩。设置dp[s][v]表示状态s下,到达节点v所用的最短时间。 其中s表示已经使用的车票原创 2016-12-23 22:34:39 · 463 阅读 · 0 评论 -
hdu1114(完全背包)
/*translation: 给出n种硬币,以及该种硬币的价值和重量。求在已知重量的条件下求出这些硬币的一个组合,使得它们的价值之和最小。solution: 完全背包dp 按照完全背包dp的解法即可。note: 1:注意完全背包采用滚动数组的写法时的第二重循环的遍历顺序。和01背包比较。date: 2016.10.31*/#include #include #includ原创 2016-10-31 21:50:41 · 389 阅读 · 0 评论 -
hdu1074(状压)
/*translation: 给出n门作业,没门作业有期限和完成所需的时间。超过期限每一天就扣掉一分。求最少扣掉多少分。并按字典序给出 作业的完成顺序。solution: 状压dp 仔细观察题意可以发现就是求作业的某一种排列顺序使得满足最优解。所以用动态规划的状态表示一定涉及到集合。 又考虑到数据量不多。所以可以用状态压缩。note: 1:注意枚举作业状态时候的顺序,见代码注释。原创 2016-10-30 17:10:32 · 246 阅读 · 0 评论 -
hdu1069(lis的长方体堆叠模型)
/*translation: 给出n中不同类型的石块,每种类型的石块长宽高都不一样。对于两块石块a,b。只有当a的底面的长宽严格小于b的长宽时, a才能摆放在b的上面。问最多能够将石块叠加到多高。solution: lis的长方体堆叠模型,dp 这道题很明显使用dp来做,(其实用搜索也可以吧,数据量不是很大)具体做法是先按照长宽或者宽长对各类的长方体进行排列。然后在直接套上lis的模型原创 2016-10-29 21:59:44 · 1895 阅读 · 0 评论 -
hdu1024(基本dp)
/*translation: 给出一串数列,求m个不相交的段最大的和是多少?solution: 基本dp。 设dp[i][j]表示前j个数划分成i段,所得到的最优解。 对于第j个数,有两种决策,一种是单独成立成一个段。另一种是和地i个段组成一段。 所以有转移方程如下:dp[i][j]=max{dp[i][j-1], max{dp[i-1][k]}} + a[i]。其中k>=1 &&原创 2016-10-29 21:56:32 · 420 阅读 · 0 评论 -
uva1638(递推关系,dp)
/*translation: 高为1...n的杆子排成一列,从左能看到l根,从右能够看到r根。求有多少排列的可能?solution: dp,递推 为了状态的转移无后效性,按照杆子的长短从小到大来排列,先排列最短的杆子。因为这样无论这个杆子放在哪里 都对后面的转态是如何转移的无任何影响。若是最短的杆子放在最右边,则接下来的状态成了dp[n-1][l][r-1] 同理,放在最左边则是d原创 2016-10-06 17:27:11 · 337 阅读 · 0 评论 -
uva242(转换成完全背包dp)
/*translation: 一个信封最多能够贴s张邮票,现在有n个邮票的集合,求能够连续覆盖最大的值的邮票的集合。并打印出能够 i连续覆盖的最大的值。solution: 完全背包dp的可行性解法 设dp[i][j]:=前i种物品能够达到j值的所用最少的张数。然后即可按照完全背包的滚动数组dp来求解。 之后从1开始遍历,一旦遇到所需张数大于s的话,那么所能够连续覆盖的最大的值就是此时原创 2017-01-15 21:01:25 · 718 阅读 · 0 评论 -
uva1631(DP记忆化搜索)
/*translation: 有一串密码锁,每次能够让相邻的1~3位数字向上或者向下旋转一格。给出目标状态和起始状态,问最少需要旋转几次?solution: 记忆化搜索dp 令dp(int pos, int a, int b, int c)其中pos是当前的位置,a,b,c分别是pos,pos+1,pos+2上的数字。此时 pos前面的位置都已经旋转完毕,不需要再次旋转了。那么就可以求原创 2017-01-16 15:43:50 · 962 阅读 · 0 评论 -
hdu1069(*记忆化搜索)
/*translation: 给出n种类型的箱子,每种箱子数量可以无限供应。当一个箱子的底面长宽严格比另一个箱子要小时才可以重叠在上面。 问最高可以叠多高?solution: 记忆化搜索即可*/#include #include #include #include using namespace std;const int maxn = 100;st原创 2017-03-23 21:27:24 · 311 阅读 · 0 评论 -
poj3420(状态压缩+矩阵加速)
/*translation: 有4*n的矩形一个,求用1*2的砖块去铺可以有几种填充方法?solution: 矩阵加速+状态压缩 一看这道题以为是轮廓dp,但是由于n的值太大,所以无法进行轮廓dp,所以考虑用矩阵来加速。 如图片所示,在第n行铺完后第n+1行的情况可以有如图所示的几种情况。注意其中0101的状态是不可能出现的。因为如果出现0101 那么最原创 2017-01-26 21:03:07 · 349 阅读 · 0 评论 -
poj1795(状态压缩dp,字符串压缩求最小字典序)
/*translation: 给出n个字符串,求一个最小长度的串,该串包含给出的所有字符串。注意该字符串在长度最小的同时还必须是字典序最小。solution: 状态压缩dp 注意到n的值比较小,所以考虑可以状态压缩。定义dp[i][s]:=在所有字符串选取情况为s的情况下,最前面的字符串为i号字符串 的最小长度。依次枚举下一个字符串可得状态转移方程 dp[i][原创 2017-01-27 12:12:32 · 1229 阅读 · 1 评论 -
poj3411(状态压缩dp,dijkstra最短路)
/*translation: 给出一张图,求节点0到节点n-1花费的最小费用。对于一条边a->b,可以有一下两种不同的付费方式: 1.在点c提前预付,但此时必须经过点c,花费为r 2.在点b支付,花费为psolution: 状态压缩dp+dijkstra dp[i][s]:=走到i点时的最优解,且此时走过的点状态为s(包括i) 然后根据dijkstra不断松弛即可。note:原创 2017-01-20 10:58:52 · 299 阅读 · 0 评论 -
poj3233(矩阵幂)
/*translation: 给定矩阵A,求A + A^2 + ... + A^ksolution: dp,矩阵幂note: * 关键在于矩阵递推式的构造,可以先写出所有的状态递推关系,然后根据这些递推关系构造出矩阵的递推式。date: 2017.1.17*/#include #include #include using namespace std;typedef原创 2017-01-19 13:13:19 · 295 阅读 · 0 评论 -
poj2836(状压dp)
/*translation: 二维平面上有n个点,现在求用长宽任意的矩形完全覆盖这些点所用的最小矩形面积总共是多少?solution: 状压dp dp[s]:=当前状态下最小面积 dp[当前状态] = min(dp[过去状态] + 矩形面积, dp[当前状态])note: # 这里注意,先对所有矩形进行预处理的时候,当要枚举的矩形的两个顶点在同一行或者同一列的点时,由于不允许面积为原创 2017-01-19 13:11:47 · 378 阅读 · 0 评论 -
poj3734(矩阵幂)
/*translation: 用红、黄、蓝、绿四种颜色对n个砖块进行染色。问红、绿砖块都为偶数的方案总共有多少种?solution: 矩阵幂,小白书p203 设染到第i块时红绿砖块都为偶数的方案为ai,红绿砖块一奇一偶方案数为bi,红绿都是奇数的方案数为ci 则可以有如下的递推: a(i+1) = 2*ai + bi b(i+1) = 2*ai + 2*bi + 2*ci c(i原创 2017-01-17 21:53:34 · 250 阅读 · 0 评论 -
uva10163(两次dp)
/*translation: 见lrj紫书p306solution: 普通dp 分成两次来求解,状态的定义以及状态转移方程见代码注释note:date: 2017.1.16*/#include #include #include using namespace std;const int INF = 1e6;int dp1[105][105]; //dp1[i]原创 2017-01-16 21:10:01 · 273 阅读 · 0 评论 -
uva1632(区间dp)
/*translation: 直线上有n个点,每个点会在经过各自特定的时间后消失。问从任意位置出发走过所有的点的最短时间是多少?solution: 区间dp dp[i][j][0]表示i~j区间里的点都走完了,且最后停留在i点。 dp[i][j][1]表示i~j区间里的点都走完了,且最后停留在j点。 具体状态转移方程见代码。note: # 一开始的思路是按照TSP解决,后来发现原创 2017-01-16 17:27:52 · 373 阅读 · 0 评论 -
uva1637(记忆化搜索,离散概率)
/*translation: lrj p327solution: 动规,记忆化搜索,全概率公式 用map, double>记录下当前的状态。然后按照记忆化搜索的dp即可note: 1:这种状态复杂的记忆化搜索不好写,怎样表示状态很关键,同时这道题一开始用double类型的d数组来记忆 导致输出nan。 2:这道题的记忆化搜索写法的状态表示值得借鉴,特别是记忆数组和状态表示。原创 2016-09-29 21:43:38 · 317 阅读 · 0 评论 -
poj2184(背包的可行性解法)
/*translation: 有n件物品,每件有两个属性:s[i], f[i]。要求选出一些物品使得在s[i]和f[i]都为非负数情况下二者的和最大是多少?solution: 一维01背包 令dp[i]表示s[i]属性恰好装满到i时,f[i]最大值是多少。由于s[i]有负数存在所以将数组开大。 具体转移方程见代码。note: 1:这类选与不选的问题很明显用背包,一开始想到的是二原创 2016-09-20 21:42:39 · 252 阅读 · 0 评论 -
poj2392(多重背包dp,可行性类型O(nm)复杂度的解法。)
/*translation: 有k种石块,每种石块有ci个,每种石块所在的高度不能超过ai,求用这k种石头所能达到的最高高度solution: 多重背包dp可行性解法,贪心 先排序,然后按照多重背包dp可行性解法即可acnote: 此题用常规的多重背包wa了,不知道为啥?date: 2016.9.8*/#include #include #include #inc原创 2016-09-19 22:07:56 · 531 阅读 · 0 评论 -
poj1065(dilworth定理+lis)
点击打开链接/*translation: n根木材长l_i重w_i,前一根木材大于后一根的话要浪费一分钟准备机器,求最省方案? solution: dp, dilworth定理, lis 此道题是求按照某一元素(长度或者重量)排序后,另一种元素最少有几个上升子序列? 这样就可以通过求另一种元素的最长下降子序列的长度,就是上升子序列的最少个数。--dilworth定理 note原创 2016-09-12 21:54:43 · 545 阅读 · 0 评论 -
poj1159(类LCS的转移方程)
/*translation: 给出一串字符串,求最少插入几个字符才能形成回文串。solution: 基本dp,LCS类转移方程 思路很简单,将原字符串及其反串求LCS,将原本字符串长度减去LCS长度就是答案。 状态定义和转移方程都和LCS一样。note: 该题目需要用滚动数组,不然会MLE。所以相应的求解方式也作出改变。详见代码。 理解滚动数组求解方式:只要画出网格图来代表原原创 2016-08-20 17:48:08 · 425 阅读 · 0 评论 -
poj1080(LCS类的转移方程)
/*translation: 题目大意是给出两个基因序列,要你求出这两个基因序列的相似度。所谓的相似度, 就是将基因串用‘-’填充使得两串长度相同后,将对应位置上的字母一一对应,再 根据题目给出的表计算出分数,由于用‘-’填充的做法有好几种,所以得分最高的那个 就作为相似度。solution: 基本dp,形如LCS的转移方程。 d[i][j]:串1选到第i-1个,串2选到第j-1原创 2016-08-20 14:49:01 · 368 阅读 · 0 评论 -
poj3267
/*solution: d[i]表示从第i个位置到最后共有多少个最少可以删去的字符。题目所求结果就是d[0] 关于状态转移方程。一开始太过与拘泥与每一步来分析。其实完全可以只考虑一些 特殊 位置。比如只考虑在给出句子中与给出字典单词的首字母相同字符的位置。这样的话, 转移方程如下: d[i] = d[i+1]+1; 在句子中所在位置的字符不是字典中任何一个单词的首字母情况 d[i]原创 2016-08-18 14:37:09 · 376 阅读 · 0 评论 -
poj2533-----E[j]=opt{D+w(i,j)} 类型板子题
最长公共子序列,做板子用:#include #include using namespace std;const int maxn = 1001;const int INF = 1e30;int a[maxn], n;int dp[maxn];int main(){ //freopen("input.txt", "r", stdin); while(~scanf原创 2016-08-19 23:44:16 · 303 阅读 · 0 评论 -
poj1260(形如E[j]=opt{D+w(i,j)}的dp)
/*solution: 形如:E[j]=opt{D+w(i,j)}的dp d[i]:选到种类i的时候所能花费的最少费用. 状态转移方程: d[i] = (a[i] + 10) * p[i] + d[i-1]; d[i] = min(d[i], d[j] + (sum[i] - sum[j] + 10) * p[i]);note: wa的原因是状态转移方程出错,原本思路是枚举比i小原创 2016-08-19 23:14:28 · 317 阅读 · 0 评论 -
poj1836(基本dp)
/*solution: 基本dp,最长上升子序列。 题目要求的其实就是一个呈三角波浪分布的一个最长序列。所以基本框架就是 枚举中间的卫兵i,j。求0~i的最长上升子序列,j~n-1的最长下降子序列。 用n减去两者的和就是答案。note: 开始之所以wa的原因是认为中间两个卫兵肯定相邻,但是其实也可以不相邻。date: 2016.8.18*/#include #inclu原创 2016-08-18 22:24:13 · 272 阅读 · 0 评论 -
poj1276
/*solution: 赤裸裸的多重背包dp dp[i]表示能够凑出金额不超过i的最大金额数。 状态转移方程还是按照01背包问题演化而来:dp[i] = max(dp[i], dp[i-c[i]]+w[i])。 只不过在这里重量和价值都看成cash[i]。note: 注意在按照01背包求解时,循环条件要注意改成k*cash[i]!!date: 2016.8.17*/#in原创 2016-08-17 20:19:26 · 203 阅读 · 0 评论 -
poj1837
/*solution: 背包型dp dp[i][j]表示选到第i个时,平衡度为j的方法数. 转移方程:dp[i][j+C[k]*G[i]] += dp[i][j];note: 1:注意初始条件的初始化 2:关于该题目中平衡度,因为在极端条件下,左右两边的极限值为:20*25*15=7500 所以极限值范围:-7500~+7500;有由于下标不能为负数,所以将平衡值从0移动为750原创 2016-08-16 20:00:32 · 211 阅读 · 0 评论 -
poj3616(LIS)
点击打开链接/*translation: 一头奶牛每天在一些特定的时间段产奶,每次产奶之后必须休息r分钟。现在给出每天的产奶间隔和 每个间隔的产奶量,求该头奶牛的一天可以产奶最高多少? solution: LIS, dp即可解。 note: 1:一开始被给出的时间n所干扰,但是这其实是无用条件。 2:善于从题目中抽象出经典模型。 3:poj上的FJ和Bessie是真爱,t原创 2016-09-01 14:38:28 · 199 阅读 · 0 评论 -
poj3280(区间dp)
点击打开链/*translation: 给出一些字母的删除和添加的代价,求出让一串给定的字符串变成回文串的最小代价。solution: 区间dp d[i][j]:从i~j变成回文串的最小代价。具体转移方程见代码。note: 1:转移方程错误。区间dp的转移方程形式上有点类似lcs,以后可以对比lcs来写区间dp的转移方程。 2:像回文,括号这些类似的问题有时候可以考虑用区间原创 2016-09-01 16:47:15 · 236 阅读 · 0 评论 -
gcj2009R1C_C(区间dp)
/*translation: 总共有p个犯人,其中要释放q个。但是释放一个犯人必须给两排直接相邻的牢房的犯人一枚金币。 直到空牢房为止,或者监狱的两端。求q个犯人全部释放最少需要多少金币? solution: 区间dp dp[i][j]表示释放i+1~j-1的犯人需要多少金币。 dp[i][j] = 此时所需金币数量 + 释放右侧部分需要的金币 + 释放左侧部分需要的金币 no原创 2016-09-06 20:43:24 · 258 阅读 · 0 评论 -
poj3181(高精度完全背包dp)
点击打开链接/*translation: 给你一定金额n的硬币,再给出k件商品,第i件商品的价格为i。用n金额有多少种购买方案?solution: 完全背包,状态以及转移方程均类似note: 1:一开始按照完全背包的写法,是错误的。但方法没错,原因在于数据问题,输入边界值1000 100, 输出的是无用的数据。明显发生了数据溢出问题。所以按照网上题解的思路,将其分成两个数组,原创 2016-09-05 16:15:52 · 1455 阅读 · 0 评论 -
uva10304(区间dp)
点击打开链接/*translation: 给一个序列即可 S = (e1,e2,...,en),且e1<e2<..<en.要把这些序列构成一个二叉搜索树。 二叉搜索树是具有递归性质的,且若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它 的右子树不空,则右子树上所有结点的值均大于它的根结点的值。 因为在实际应用中,被访问频率越高的元素,就应该越接近根节点原创 2016-09-05 16:13:10 · 345 阅读 · 0 评论 -
poj1390
/*solution: 区间dp,加状态参数。 如果只是用状态dp(i, j)来描述消去方块i到方块j获得的分数是无法形成递推关系的。 因为在这个时候对于最右边的大块有两种选择,一是直接消去,二是将其与左边某个大块 合并删除。而对于选择二来说,删去未必是最有方案,也许还应该与左边的某方块合并后 消去。所以只有两个参数是无法准确描述状态并形成递推关系的。解决方原创 2016-08-13 22:35:22 · 643 阅读 · 0 评论 -
poj3666(离散思想,lis,dp)
/*translation: 给出一列数列,问把这列数列变成非递增或者非递减的最小代价是多少。代价公式如下: |A1 - B1| + |A2 - B2| + ... + |AN - BN |。solution: dp, lis, 离散化 每个数要增加多少的量是不确定的,也就是有无穷种可能。但仔细考虑,要使得代价最少,增加后的量肯定 是原来的数列当中的数。因此先把原来数列排序。在用l原创 2016-09-16 21:45:19 · 480 阅读 · 0 评论