![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
HumveeA6
这个作者很懒,什么都没留下…
展开
-
poj 1050 To the max(二维最大子串和,最大子矩阵)
这道题其实是一维上的最大子串的一个推广。如果对于一个数列,要求他的最大子串(定义与本题类似)那么一维的时候有两种类似的做法。1.一维的时候,就是要找一个l,r 让前缀和sum[r]-sum[l-1]最大,然后从左往右扫的时候,扫到i的时候 用一个min存sum[j] (j=1,2,...,i-1)的最小值 然后sum[i]-min就是以i为右端点的区间的最大值,然后用sum[i]更新m原创 2018-02-01 15:59:13 · 273 阅读 · 0 评论 -
Codeforces 392B
题意:在原来的汉诺塔基础上,给每次移动加上一个权值,Tij表示从rodi移动到rodj的花费。 求把n个盘子从rod1移动到rod3上的最少花费。 题目提示是dp….也确实如此,dp[n][i][j]:表示把 n 个盘子从 rodi 移动到 rodj 上的最少花费; 决策有两个: 1. 将rod1上的n-1个盘子移动到rod2上,将rod1上的最后一个移动到rod3上,再将rod2上的n-...原创 2018-03-14 16:55:21 · 187 阅读 · 0 评论 -
POJ2385
明显dp,但是关键是如何解决后效性的问题,因为可以走的次数是有限的,前面用完了后面就不能用了。那么最好的方法就是考虑每一次下的所有可能——dp[i][j][k]表示在第i次掉落苹果后,转移了j次,此时奶牛在第k+1棵树下时所能吃到的最多的苹果。 那么,dp[i][j][k]=max(dp[i-1][j][k],dp[i-1][[j-1][k^1]),如果这次苹果掉在k+1,那么还要加1.当然,还...原创 2018-03-30 17:36:41 · 289 阅读 · 0 评论 -
POJ3616
题目其实不难,关键是如何定义一个dp。将时间段按结束时间从小到大排序,定义dp[i]为第i个时间段dp[i]被使用后所能挤奶的最大值。dp[i]满足如下递推关系: 第i个时间段挤奶的最大值 = 前 i – 1 个时间段挤奶最大值中的最大值 + 第i次产奶量。 这么搞有一个好处,就是每个时间段都必然有被选中的机会(dp[i]以第i段时间为结尾),因此出来的结果必然是考虑了所有区间之后最优的。...原创 2018-03-30 19:49:52 · 202 阅读 · 0 评论 -
cccc2016决赛9
刚看到题并不知道怎么做,想了一会感觉似乎网络流可以搞,乱写了一通交上去然后发现tle了60%的点然后滚粗了。然后发现这题其实是在求在整个数列中最多有多少个下降的子序列,那么就可以用到dilworth定理的推论了:一个序列中不上升子序列的最小覆盖数=序列中最长上升序列的长度。那么剩下的就是一个onlogn的问题了。#include<cstdio>#include<iost...原创 2018-03-21 10:37:25 · 301 阅读 · 0 评论 -
POJ3280
题意:对一个字符串进行插入删除等操作使其变成一个回文串,但是对于每个字符的操作消耗是不同的。求最小消耗。 思路: 我们定义dp [ i ] [ j ] 为区间 i 到 j 变成回文的最小代价。 那么对于dp【i】【j】有三种情况 首先:对于一个串如果s【i】==s【j】,那么dp【i】【j】=dp【i+1】【j-1】 其次:如果dp【i+1】【j】是回文串,那么dp【i】【j】=dp【i...原创 2018-04-01 16:33:32 · 913 阅读 · 0 评论 -
logn的最长公共子序列
最长公共子序列(LCS)最常见的算法是时间复杂度为O(n^2)的动态规划(DP)算法,但在James W. Hunt和Thomas G. Szymansky 的论文”A Fast Algorithm for Computing Longest Common Subsequence”中,给出了O(nlogn)下限的一种算法。 定理:设序列A长度为n,{A(i)},序列B长度为m,{B(i)},考虑...原创 2018-04-02 20:53:07 · 360 阅读 · 0 评论 -
POJ1014 多重背包
很simple,背包容量为总价值数/2,如果能凑出来就OK,不行就不ok。#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;int c[20005],cnt=0;bool v[120005];void...原创 2018-04-10 12:51:15 · 334 阅读 · 0 评论 -
POJ3181
完全无脑的完全背包水题,但是要写高精度,不然会爆…顺便吐槽poj不支持__int128…#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;struct data{ int len; int...原创 2018-04-03 20:00:03 · 256 阅读 · 0 评论 -
POJ1065
显然这是一个要寻找所给的木棍经过任意排序后最少能分成多少个不下降子序列的问题。但是因为有两个维度,因此很难做。我们可以先按一个键值进行从小到大排序,然后在剩下的序列中再寻找不下降的子序列。这个可以根据diworth定理在nlogn的时间内完成。考虑到lower_bound的查找特性,我们不妨从大到小排列然后再查找(也就是找反面)。#include<cstdio>#includ...原创 2018-04-11 15:56:17 · 430 阅读 · 1 评论 -
POJ2392
题目显然是一个比较复杂的多重背包。因为现在每个方块还有独自的高度限制。那么我们就把方块按他们的最大限制高度排序后再做分解即可,注意分解的时候分解后的每个方块高度要在原来方块基础上乘上块数。#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>usin...原创 2018-04-11 17:09:07 · 303 阅读 · 0 评论 -
Aizu 2200/AOJ2200
题目大意:快递到了:你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处。而且岛上只有一条船,下次想走水路还是得回到X处才行;两个镇子之间可能有两条以上的水路或旱路;邮递员必须按照清单上的镇子顺序送快递(镇子可能重复,并且对于重复的镇子不允许一次性处理,比如ABCB的话...原创 2018-03-06 08:54:29 · 448 阅读 · 0 评论 -
POJ2229
很简单的一个dp,晚上却调了半天…果然还是蒟蒻一枚… 最简单的想法就是当成完全背包来做,n是总容量,然后有不超过20种物品(1<<20 >1000000) dp[0]=1,其余皆为0即可。但是,会tle… 代码如下:#include<cstdio>#include<iostream>#include<cstring>usi...原创 2018-03-18 23:03:08 · 567 阅读 · 0 评论 -
poj 2279 dp做法
这题用dp貌似会爆内存吧…数组有点大,反正dp做法只是参考 对于题目,我们将学生按高度从高到矮安排,那么这样的话其实在每一行的层面肯定是可以保证左边比右边高的,因为前面安排的都是更高的学生。 安排新的学生时,对于每一行有如下考虑: 1.该行未满 2.行号为1,或者该行的学生数比上一行少(这样的话,就能保证如果新插入学生,那么这个学生的高度也比上一行同一位置的学生高度低)f[a1][a2原创 2018-02-02 11:20:19 · 1716 阅读 · 2 评论 -
LCIS 最长公共子序列(joyoi)
题目是LIS 和 LCA 的结合,用f[i][j]表示a1~ai,b1~bj可以构成的以bj为结尾(这点很重要!!!)的LCIS长度。#include#include#include#includeusing namespace std;int f[3005][3005], a[3005], b[3005];int main(){ int n, i, j, k;原创 2018-02-03 17:48:36 · 209 阅读 · 0 评论 -
POJ 3585 (dp)
一眼看过去还以为是网络流,想想复杂度好像高了点…后来发现书上是做了树上的dp(二次扫描,换根)…emmm,反正还是觉得挺神奇的。思路可以看进阶指南p267…#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<vector&g...原创 2018-02-08 20:35:21 · 552 阅读 · 0 评论 -
TYVJ 1061 Mobile Service(dp)
原题地址http://www.joyoi.cn/problem/tyvj-1061 原题似乎有个地方没有说清楚,就是地址是从0到L之间的整数… 最简单的想法是用f[i][j][k][s]表示完成了第i个请求时,三个服务员分别在j,k,s的服务费用。然而这样的话时间复杂度以及空间复杂度都很高。仔细观察可以发现其实在每个状态下,有一维是多余的——完成了第i个任务的时候,肯定有以一个服务员在第i个任原创 2018-02-04 10:59:13 · 240 阅读 · 0 评论 -
NOIP 2008 t3 (洛谷p1006)
题目不难,就是各种边界处理要考虑一下#include#include#includeusing namespace std;int f[101][51][51], map[51][51], n, m;int main(){ cin >> m >> n; int i, j, k; for (i = 1; i <= m; i++) for (原创 2018-02-04 11:47:52 · 171 阅读 · 0 评论 -
POJ2228 环形dp
题目详细做法可参考进阶指南p271,总之这是环形dp的一种,策略是执行两次dp,第一次在任意位置断链成环,按照线性dp求解,第二次则通过赋值和限制条件,算出把断开的位置连上的状态的解,然后比较两次dp的结果#include <iostream>#include<cstdio>#include<cstring>using namespace std;...原创 2018-02-11 17:25:16 · 906 阅读 · 0 评论 -
POJ 2411(状压dp)
用f[i][j]表示第i行形态为j时,前i行的分割方案总数,j是用十进制记录的m位二进制数,j的第k位为1表示第k列是一个竖着的1*2长方形的上面一半,第k位为0表示其他情况 第i-1行形态k能转移到第i行j有两个要求: 1.k&j==0 这保证了每个1 下面一定是0,即继续补全竖着的1*2的长方形 2.k|j中的0一定是成对出现的 (每一段连续的0必然有偶数个),保证横着放1*2...原创 2018-02-12 09:18:20 · 300 阅读 · 0 评论 -
背包问题初始化的一点小问题
初始化的细节问题我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。如果并没有要求必须把背原创 2018-02-07 10:55:42 · 281 阅读 · 0 评论 -
POJ 1742 Coins
明显dp题,但是如何高效dp则是个问题; 令dp[i][j]表示用前i种硬币表示面值j时第i种硬币最多能剩多少个,那么, 1.如果dp[i-1][j]>=0,也就是前i-1种就能拼出j的话,那么dp[i][j]自然就是c[i]了; 2.如果j < a[i](第i种的面值)或者dp[i][j-a[i]]<=0(j比a[i]小或者用前i种根本就拼不出j-a[i]),则dp[i]...原创 2018-02-08 10:12:55 · 173 阅读 · 0 评论 -
洛谷P1020 (Lower_bound与Upper_bound的使用)
题目的第一问在求最长不上升子序列,第二问则是求最长上升子序列,至于第二问为什么这里不加以证明。 对于这种数据,传统的LIS肯定是会tle的,所以不妨采用新的方法。这里要说一句STL大法好哇! LIS O(nlogn)的解法如图: 函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回las...原创 2018-03-10 13:37:38 · 320 阅读 · 0 评论 -
POJ 1179 (DP)
关键就是要想到最大值可能是负负得正得来的,所以我们还需要维护区间的最小值,别的就不难了,很单纯的区间dp lyd的书上的详解: #include<cstdio>#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<...原创 2018-06-06 23:04:06 · 251 阅读 · 0 评论