
动态规划
文章平均质量分 71
incredible_bly
这个作者很懒,什么都没留下…
展开
-
动态规划专项intermediate:UVa 10271
刚开始就是无脑的记忆化搜索,复杂度为O(k*n^2),果断TLE。后来改成递推的时候发现可以优化到O(k*n)。需要先将输入的数降序排列(这样第i组从第3*i个开始递推,这保证了解的可行性)。状态转移方程为:dp[i][j]=min{dp[i][j-1],dp[i-1][j-2]+(c[j]-c[j+1])^2},状态表示从前j个筷子中选择i组筷子所能取得的最优解。#include #i原创 2013-04-04 23:04:27 · 488 阅读 · 0 评论 -
动态规划专项intermediate:UVa 10688
可以把问题转化成区间来考虑。dp[i][j]表示从i到j所需吃掉的苹果。这样状态方程就出来了dp[i][j]=min{dp[i][k-1]+dp[k+1][j]+(k+K)*(j-i+1)|i边界条件为i==j时dp[i][j]=0;i==j-1时dp[i][j]=2*(i+K);i==j-2时,dp[i][j]=3*(i+K+1)。#include #include #inclu原创 2013-05-08 22:23:14 · 576 阅读 · 0 评论 -
动态规划专项intermediate:LA 4015
被自己蠢哭了……已经想到是dfs里分组背包,可就是不知道怎么写,看题解才知道怎么做,然后细节和边界条件又想了半天才弄明白。其实就是用dp[i][V][0]表示以i为根结点遍历V个点并回到i所需的最小能量,dp[i][V][1]表示以i为根节点遍历V个点(不需回到i)所需的最小能量。然后就是分组背包了,然后还得注意边界条件,因为V个点作为物品必须全部取完,所以边界为dp[root][1][0原创 2013-05-09 22:03:47 · 690 阅读 · 0 评论 -
动态规划专项intermediate:UVa 11766
这道题关键就是模型的转化,只要把a、b两个值转化为一个[a+1,n-b]的区间问题就很容易考虑了。这样问题就变成了求区间[1,n]上无重叠部分区间的最大值,但有一点不同的是,完全相同的区间最多可以取区间长度个,即n-a-b个。最后,n减去dp所得的值即为结果。#include #include #include #include using namespace std;struct原创 2013-05-15 21:31:41 · 712 阅读 · 0 评论 -
动态规划专项intermediate:UVa 11400
先贪心一下,就是要么用当前的v来买,不然的话就向更高的下一个v传递,而不可能出现跨级传递。(不知道说清楚了没……)然后就很简单了先按v排一下序,dp[cur][pre]表示到达cur时,pre表示之前还未买的最低等级。状态转移方程为:dp[cur][pre]=min{dp[cur+1][pre],dp[cur+1][cur+1]+p[cur].k+p[cur].c*(sum[cur]-su原创 2013-06-02 12:33:20 · 619 阅读 · 0 评论 -
动态规划专项intermediate:UVa 10599
不难发现路径是以garbage为结点的,所以可以根据garbage的相对顺序建图进行dp,与此同时也可以递推出最长路径的数量。至于打印路径,根据dp得出的结果再dfs一遍即可。#include #include #include #include using namespace std;typedef long long LL;const int maxn=110;int r,c原创 2013-07-11 22:36:38 · 726 阅读 · 0 评论 -
动态规划专项intermediate:LA 4490
刚开始是用记忆化搜索做的,貌似是贪心出了问题,各种WA。后来搜了下AC的代码,清一色的递推。刚开始看不懂,可能是因为什么dp都用记忆化搜索做的,显然,递推更考验思维而且时间复杂度比记忆化搜索低,以后得多用递推做题啊。找了一道写的相对简单的代码,看懂了之后写,还T了几炮……大概思路就是4维dp,dp[i][j][k][p]表示进行到第i本书,移动了j本书,k是已经摆放了的书的高度的集合,p是原创 2013-06-29 22:50:41 · 754 阅读 · 0 评论 -
动态规划专项intermediate:LA 4327
一道用单调队列优化的dp,算是第一道,搞了一晚上,结果1A,还是比较有成就感的。状态转移方程很容易得出:dp[i][j]=max{dp[i-1][k]+sumW[i][j-->k or k-->j]|sumL[i][j-->k or k-->j]可是这样的话时间复杂度为O(n*m^2),显然难以接受。可以发现状态转移可以转化为定长区间求最大或最小连续和,很明显的单调队列。每一层需要原创 2013-07-02 23:56:20 · 729 阅读 · 0 评论 -
动态规划专项advanced:LA 4394
关键是贪心出一个性质,即每次刷一个串,都可以从头开始刷起,如果第一个字符相同,则从第二个开始刷,而每次刷要么只刷一个字符,要么刷到另一个与目标串首字符相同的字符为止。只要发现了上述性质,转移就不难写了。我写的是3维的dp[L][R][C],L、R表示待刷的字符串的区间,C表示该字符串的状态,如果C为0则表示该串未被刷,而当1状态转移方程为dp[L][R][C]=min{1+dp[L原创 2013-08-06 23:12:55 · 1267 阅读 · 0 评论 -
动态规划专项intermediate:UVa 12002
这道题还是体现了我思维能力比较弱。虽然很容易想到把问题转化成LCS和LDS。但是碰到盘子大小相同时,就把我给难住了……(和又一次周赛的一道DP如出一辙!)看了题解才知道,可以先把LCS和LDS先dp出来,然后再用2个for扫一遍就可以得出结果了。思维还是被局限了,老想改dp来解决问题啊,思维还是得多加锻炼!#include #include #include #include us原创 2013-05-06 21:01:08 · 717 阅读 · 0 评论 -
动态规划专项intermediate:UVa 10981
直接用map记录状态,1表示该状态可以达到目标状态,0表示不能。然后从左到右dfs,然后一旦得到的返回值为1,就记录路径,然后返回。记录路径也可以用map来实现。本来以为用stl会很慢,结果也只跑了19ms。#include #include #include #include using namespace std;string s,t;map dp;map path;int原创 2013-05-05 21:00:36 · 598 阅读 · 0 评论 -
动态规划专项intermediate:UVa 10304
这道题lrj的书上给出了相当详细的解释,为了图省事就直接用记忆化搜索O(n^3)的复杂度写了,极度之搓……最后4s+极度水的过了……#include #include #include #include using namespace std;#define M 300int dp[M][M];int f[M];int s[M];int n;int dfs(int i,in原创 2013-04-05 22:07:48 · 487 阅读 · 0 评论 -
动态规划intermediate:UVa 11456
这道题刚开始想的比较复杂,后来发现序列所选取的第一个元素加上之后的最长上升和下降子序列即为最长的序列。只要dp一遍就行了,复杂度为O(n^2)。#include #include #include #include #include using namespace std;#define M 2010int a[M],n;int dp1[M],dp2[M];int main(原创 2013-04-08 01:37:31 · 470 阅读 · 0 评论 -
动态规划intermediate:LA 4945
这道题状态转移方程一直想不出来……最后搜到了一份贪心的代码,模仿着过了,其实还是有点一知半解……大概思想就是按Petra的选择将goodies排序。先假定按Petra的选择逐个选取,然后从后往前将Jan的选择改为最优。至于这样贪心的正确性,其实我不是十分清楚……唉,思维弱是硬伤啊!#include #include #include #include #include #includ原创 2013-04-08 01:35:49 · 556 阅读 · 0 评论 -
动态规划intermediate:LA 6042
需要小贪心一下,并且需要双向dp。dp[cur][pos]表示进行到第cur个tower,并将该tower移至pos时所需的最小cost。转移方程为:dp[cur][pos]=min{dp[cur-1][i]+h[cur]*abs(p[i]-pos)|pos-w dp[cur][pos]=min{dp[cur+1][i] +h[cur]*abs(p[i]-pos)|po原创 2013-04-09 23:05:02 · 460 阅读 · 0 评论 -
动态规划intermediate:UVa 10239
一开始看错题了,以为书是任意排列的,结果怎么样也搞不出状态方程……后来看了题解才发现顺序是固定的,这样这题就成水题了……状态转移方程为:dp[cur]=min{dp[i]+max{h[j]|cur为了避免精度问题,可以把浮点数转化为整数来做就行了。#include #include #include #include #include using namespace std;原创 2013-04-16 23:08:15 · 533 阅读 · 0 评论 -
动态规划intermediate:UVa 10604
令人无语的一道题,因为数据比较小,上来就直接无脑的用状压来做了,可能是因为写的实在太搓,居然T了。后来改成把每个药品的数量用4位二进制表示,用位运算做,然后WA了……样例实在太恶心了,居然a和b混合与b和a混合产生的热量可能不同……最后跑了1.7s极度水的水过了。看UVa论坛上说可以用6维dp做,试着写了下,发现不会实现啊!看statistics里各种几十ms过的我就汗了。求好心的高手指点。。原创 2013-04-16 23:10:46 · 487 阅读 · 0 评论 -
动态规划专项intermediate:UVa 11600
一道求数学期望的dp,刚开始因为概率论没学好的缘故,连样例都看不懂……后来因为做了一道概率题,才明白了样例。做出来之后发现其实只是道水题……先把连通分量都缩成一个点,然后就是简单的状压了。因为n到达30,数组开不下,所以我是用map实现状压的。状态转移方程:dp[i][st]=(n-1)/(n-s)+sum{cnt[k]*dp[k][st^(1k表示未访问过的节点,cnt[k]表示节点原创 2013-04-26 21:55:38 · 1072 阅读 · 0 评论 -
动态规划专项intermediate:UVa 10934
这道题想了很久,最后还是功亏一篑。看了大牛的代码,一下就懂了。状态表示用i个球j次尝试所能测试的楼的最高层数。不妨假设,第一次在某一层测试,如果球没有爆,那么往上至多测试dp[i][j-1]层;如果爆了,那么往下至多测试dp[i-1][j-1]层。状态转移方程:dp[i][j]=dp[i][j-1]+dp[i-1][j-1]+1。#include #include #include原创 2013-04-28 21:00:35 · 674 阅读 · 0 评论 -
动态规划专项advanced:LA 4625
这道题要求解的问题是使最大值最小的问题,所以可以加一个参数加以限制,然后判断是否可行用二分的方法求解答案。这里二分每个half-segment上的最大重量,然后剩下来需要做的就是判断是否存在一个方案满足该条件。容易想到的是贪心,即每一段取尽量多的pieces,看m-1段能否将pieces全部取完,然而这个贪心是错的。看这样一个例子:n=8,m=4,d=10,w[]={7,7,1,1,5,5原创 2013-08-19 00:32:57 · 704 阅读 · 0 评论