![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
文章平均质量分 59
子在梦中曰
程序是蓝色的诗
展开
-
对于校赛F题的一些思考
F MinpathTime Limit:1000MS Memory Limit:65536KTotal Submit:61 Accepted:10Description一只兔子要从点0捡到许多金子,它要回到家点n(图中点11),但它只能通过1到n-1石板才能到家,石板分为多层,每层必须经过一个石板(如图,1、2、3、4为一层,5、6、7为一层,8、9、10为一原创 2013-04-15 20:16:36 · 537 阅读 · 0 评论 -
hdu 2639 Bone Collector II(第K大背包)
晕了,在我wa了N多遍之后,我才发现我是把体积和价值弄反了。做这道题的时候遇到的很关键的一个问题,往哪儿去产生那么多的值?在我们正常的印象里,背包求的就是一个最优值,dp[i][j]就是在大小为j的包里加入第i件物品时的最优值。所以问题产生了,我们凑不够K个值。但是仔细想想,为什么我们会认为dp[i][j]是最优值,很简单,因为它淘汰掉了其他所有的值,证明它就是最优的。而在求第K大背包原创 2013-07-12 08:34:20 · 854 阅读 · 0 评论 -
poj 3186 Treats for the Cows(DP)
yyf屁颠儿屁颠儿地跟我说他找了一个水DP,看他现在还没有A掉,其实也没那么水,哈?!刚开始他的想法是从两头比较,价钱低的那个先卖出去,价钱高的留在后面。但是这样的话如果价钱相同就不知道怎么办了。我想了一下,用两个数组分别记录从前到后和从后到前两种序列,在第k天,dp[i][j]=Max(dp[i-1][j]+k*a[i],dp[i][j-1]+k*b[j])。这样想倒是不错,但是数据规模原创 2013-07-22 20:42:52 · 712 阅读 · 0 评论 -
hdu 2845 Beans (DP)
虚拟赛一共就做了俩题。。。。这道题是先算出每一行能够取道的最大值,dp[i]=Max(dp[i-2]+a[i],dp[i-3]+a[i]),然后观看每一列,我们发现求每一列的最大值也是这个状态转移公式。然后再求一遍就行了。#include#include#define N 200005int a[N],b[N];int Max(int x,int y){ if(x>y) r原创 2013-07-24 17:20:23 · 586 阅读 · 0 评论 -
hdu 2881 Jack's struggle(DP)
对于所有的任务所在的地点按照时间排序,可以将其看成是一道非常简单的“天上掉馅饼”的题的二维版本。将这些任务看成从天而降的馅饼,统计有那些之前馅饼掉落的位置可以在两者时间差内到达给点,取其最大值。这道题的数据很邪门,题目没有给出任何提示,但是用C++提交的话会超时,用G++提交的话3000+ms可以A掉,查了1700ms。我看提交的代码都是G++。这不合适吧?#include#incl原创 2013-07-29 17:30:32 · 856 阅读 · 0 评论 -
poj 2096 Collecting Bugs(期望DP)
用dp[i][j]表示在i中类型的软件里发现了j种bug,第j种bug有四种可能:1、一种已经发现的bug在已经发现bug的子系统中找到;2、一种尚未发现的bug在已经发现bug的子系统中找到;3、一种已经发现的bug在尚未发现bug的子系统中找到;4、一种尚未发现的bug在尚未发现bug的子系统中找到;可以得到状态转移方程:dp[i][j]=dp[i][j]*i/n*j/s+原创 2013-08-05 09:49:45 · 605 阅读 · 0 评论 -
poj 1787 Charlie's Change(背包问题输出路径)
好久没写背包了,刚一上手有点儿不知道怎么写。刚开始的时候我想当然的用一个脑残的方法写了个脑残的代码,测试了六七个自己设计的脑残数据,竟然还全部通过了,提交WA。后来发现了错误,认认真真重新写了一遍,提交TLE。。。。然后是漫长的优化,我想到的优化方案是背包九讲多重背包中提到的将物品数量利用二进制思想转化的方法,但是代码写出来,输入10000,10000,10000,10000,等了半天也没原创 2013-08-07 11:06:32 · 806 阅读 · 0 评论 -
poj 2063 Investment(背包问题)
很简单的一个背包,题目中已经说了所有债权的价格都是1000的整数倍,那直接把价格和资本都除以1000就行了。因为数据很小,直接每年都重新选一次债权。我脑子缺氧算的1000000除以1000等于100,wa了三遍才发现错在哪儿了。。。。。#include#include#define N 100005int dp[N];int a[15],b[15];int Max(int x,i原创 2013-08-07 15:33:21 · 726 阅读 · 0 评论 -
hdu 1712 ACboy needs your help(分组背包)
第一道分组背包,很是让我费解了一番。第一次上来写了一个把每一组的每一种情况当成一个物品的代码,这个明显是不对的,不过我还是提交了,无悬念wa。我这是什么心态?难不成想着要是A了就不用去看分组背包的资料了?分组背包需要解释的也就一点,第二重循环和第三重循环和常规背包的位置相反。这是为了让在每一组物品都只取一件。至于原因,把dp数组用二维表示写一下,不用代码种这种用滚动数组优化过的方式表示,就原创 2013-08-07 16:54:49 · 403 阅读 · 0 评论 -
hdu 3507 Print Article(斜率优化DP)
关于斜率优化请看这个链接:斜率优化首先,我们可以简单的得到一个n^2的状态转移公式:dp[i]=dp[j]+(sum[i]-sum[j])^2+m。这个复杂度太高,肯定不能用。我们假设在求dp[i]的时候j比k更优秀,我们可以得到一个不等式:dp[j]+(sum[i]-sum[j])^2>dp[k]+(sum[i]-sum[k])^2+m。把这个不等式整理之后可以得到:(dp[j]+sum原创 2013-08-19 16:03:51 · 483 阅读 · 0 评论 -
hdu 3182 Hamburger Magi(状态压缩DP)
这道题做得很有成就感!虽然被某牛称为水题。。。假如把题目给的数据放入一个n*n的矩阵中,对于每一层第i个格子为1,表示做出了第i个汉堡,为0表示没有做出这个汉堡。那么这一层可以做出这个汉堡的条件就是做出这些汉堡的前提条件全部满足,即做这个汉堡需要做的另外几个汉堡都已经做好。由此可以得到两层之间的状态转移关系。需要特别注意的是,因为每个汉堡都只会做一个,除了前提条件满足之外,还要求这个汉堡没有做原创 2013-08-19 19:41:53 · 702 阅读 · 0 评论 -
hdu 1074 Doing Homework(状态压缩DP)
这道题输出求最优解很简单,麻烦的是怎么保证输出顺序。开始的时候我想的是在每一次状态转移的时候都加入一个深搜操作,想了想觉得好麻烦,而且这道题被某牛称为水题。看看某牛是怎么解决这个输出顺序的问题的:#include#include#include#include#define N 16#define M 99999999int st[N];struct node{ c原创 2013-08-20 22:11:46 · 424 阅读 · 0 评论 -
hdu 3001 Travelling(模拟三进制状态压缩)
集训终于结束了!感觉有些东西还不是特别清楚,等这个专题全部做完之后回来再做一遍。#include#include#define N 12#define inf 0x3f3f3f3fint dp[60000][N],map[N][N],mark[60000][N],s[N];int Min(int x,int y){ if(x<y) return x;原创 2013-08-22 22:22:20 · 463 阅读 · 0 评论 -
hdu 4576 Robot 杭州邀请赛第一题
比较水的概率DP。#include#include#include#define N 1605#define M 45struct node{ int x,y;}h[N],c[N];char map[M][M];int cmp(const void *a,const void *b){ node *c,*d; c=(node *)a; d=(原创 2013-08-11 23:17:25 · 495 阅读 · 0 评论 -
poj 2411 Mondriaan's Dream(状态压缩DP)
看到discuss里面有人在晒各种20+行的代码,太犀利了!开始一直想不到怎么编码,后来还是看了别人的思路,横着放记录为11,竖着放记录为竖着的01,即在该行为0,在下一行为1。这样的,第一行的初始状态中就不能出现连续的奇数个1,而且两行之间没有竖着的00。在两行合并的时候,同样不允许出现(j&k)中出现连续奇数个1(凡是在上一行是竖着放的,j&k后都为0),而两种状态加合的前提是(i|j==原创 2013-08-23 13:16:25 · 552 阅读 · 1 评论 -
poj 3311 Hie with the Pie(状态压缩DP+最短路)
用弗洛伊德算法预处理数据,然后送货员的路线可以理解为从0出发经过所有点,在其中任何一点停止,然后从这点回到0。从最后的点回到起点所需要走的路程经过预处理之后是可以直接得到的,需要计算的是从起点经过所有的点所需要的最短路程。#include#include#define N 11int dp[1<<N][N],dis[N][N],st[N];int Min(int x,int y){原创 2013-08-23 22:03:45 · 583 阅读 · 0 评论 -
hdu 3496 Watch The Movie(分组背包)
整天在机房写代码,偶尔确实容易脑子缺氧。一直没有注意到,如果电影看不完就输出0。。。。#include#include#define N 105int dp[N][N*10];int a[N],b[N];int Max(int x,int y){ if(x>y) return x; else return y;}int main(原创 2013-08-12 16:02:39 · 419 阅读 · 0 评论 -
hdu 3033 I love sneakers!(长姿势了,分组背包)
这道题比较难处理的地方是怎么保证选取的鞋子里每一种品牌至少要选一种。所有的值都初始化为-1,dp[0][1~m]为0。在选取每一种品牌的时候,一定要注意不能像套用背包九讲中滚动数组优化过的状态转移方程。实际上,在计算新的一种品牌的值的时候,所有的值都应该初始化为-1,这样才能保证之前计算的数据必须加上当前这组的某一款鞋子才能出现合法值。这道题很邪门的一个地方是数据中有代价为0的物品,这就需原创 2013-08-12 16:57:42 · 575 阅读 · 0 评论 -
hdu 4628 Pieces(状态压缩DP)
比赛的时候怎么就不会做,要是有多菜!直接把所有的回文串状态存下来,然后就变成很直白的状态压缩DP了。#include#include#define N 17int st[1<<N],dp[1<<N];int n;char s[N];int Min(int x,int y){ if(x<y) return x; return y;}int judge(int x)原创 2013-08-25 00:23:47 · 455 阅读 · 0 评论 -
poj 3254 Corn Fields(状态压缩DP)
我的第一道状态压缩DP,神奇的二进制。对着别人的代码思索了思索了许久才弄明白。然后自己写了一遍,忘了对M求余,wa了一次。最起码在这道题中,实际上通过状态压缩并没有减少运算量,但是通过二进制来比较不同列的两种状态的效率非常高。实际上思路还是挺暴力的。。。。#include#include#define N 13#define M 100000000int s[N],f[N][1原创 2013-08-14 15:36:40 · 479 阅读 · 0 评论 -
hdu 1565 方格取数(1)(状态压缩DP)
终于可以写题解了。因为一个细节上的失误,让我重新修改的代码一直通不过测试,郁闷。代码毫无参考价值,刚学的状态压缩DP,代码写得很难看。#include#include#define N 21int dp[1<<N],flag[N],mark[N][N],t[1<<N];int n,st[1<<N],ss;int Max(int x,int y){ if(x>y)原创 2013-08-14 23:07:32 · 531 阅读 · 0 评论 -
hdu 2167 Pebbles(状态压缩DP)
数据处理起来很恶心。感觉加这个用字符串输入没什么必要,除了让人容易把题目理解错。。。。#include#include#include#define N 16int dp[N][1<<N],flag[N],st[1<<N],a[505],mark[N][N];int ss,tt;char t[N],s[N][N*5];int Max(int x,int y){ if(x原创 2013-08-15 19:43:21 · 502 阅读 · 0 评论 -
poj 1185 炮兵阵地(状态压缩DP)
当你想要让代码A掉的时候,它一直不知名的wa,那绝对是一件非常痛苦的事儿;但是当你想要代码出点儿bug的时候,它测试数据全部通过,提交之后AC,其实也蛮蛋疼的。因为刚学状压,所以我顺着思路把这个代码写出来,想着绝对bug满天飞,然后我就在debug的过程中来理解这个算法的各种细节。结果,它A了!然后我就只能郁郁寡欢地来写题解了。#include#include#define N 1原创 2013-08-16 10:03:27 · 553 阅读 · 0 评论 -
hdu 3732 Ahui Writes Word(多重背包的二进制思想优化)
看到题目的数据我直接就懵了。100000件物品,10000大小的包,1s的时间,处处都是违和感。首先根据物品的费用和价值将物品非常121中,就是11^2。将题目转化成一个多重背包,转化成多重背包之后还不能直接A掉,因为实际上效率提高地很有限,甚至可以说根本没有提升。这里就要用到背包九讲中提到的二进制思想的优化。优化过后359msAC。#include#include#define N原创 2013-08-16 11:19:47 · 561 阅读 · 0 评论 -
hdu 2844 Coins(多重背包优化)
一个需要用到二进制思想优化的多重可行性背包问题。。。。在一个多重背包前面加那么多前缀是不是听起来很高端的样子?可惜再高端也改变不了这是个水题,而你是个菜鸟的事实。。。#include#include#define N 105int a[N],b[N],dp[100005];int main(){ int n,m; while(scanf("%d%d",&n,&m)原创 2013-08-16 20:00:59 · 468 阅读 · 0 评论 -
hdu 4539 郑厂长系列故事——排兵布阵(状态压缩DP)
跟炮兵阵地的代码差不多,思路完全相同,但是不知道为什么我用滚动数组优化的代码就是通不过。郁闷!明天起床再好好检查一下。#include#include#define N 11int mark[105][N],dp[105][200][200],flag[105],st[1<<N],num[1<<N];int fun(int x){ int cnt=0; while原创 2013-08-17 23:50:32 · 538 阅读 · 0 评论 -
hdu 1025 Constructing Roads In JGShining's Kingdom(最长上升序列n*logn算法)
用线段树实现求最长上升子序列,把复杂度降低到了n*log(2n)。#include#include#define N 500005struct node{ int x,y; int max;} a[N*3];int b[N];int Max(int x,int y){ if(x>y) return x; return y;}v原创 2013-09-01 14:22:06 · 612 阅读 · 0 评论 -
hdu 1224 Free DIY Tour(动态规划)
前天练习赛的时候,我把其他五道题做完,剩下三道我觉得比较难的题。其中两个是大数,还是特别麻烦的那种,看了看觉得做不出来。这个题目我开始以为是要用迪杰斯特拉算法做一些优化,算法我都忘得差不多了,就不做题了,直接去复习算法了。结果今天看了一下,这道题完全可以用DP去算。就是一个最大最长子序列的变种。把每一个城市的结构体里添加两个元素,一个是flag,一个是pre。pre初始化为这个元素自身的下标,原创 2013-04-06 08:45:36 · 572 阅读 · 0 评论 -
hdu 1081 To The Max(最小子阵和)
想了好久才明白。网上看别人的解题报告,对于最大连续子序列的算法已经非常熟悉了,但是理解这道题还是花了很长时间。对于单行的最大连续子序列,我引用一下我之前写过的一篇博客:最小子段和问题的通用转移公式是ans[i]=max(ans[i-1]+a[i],a[i])。ans[i]是前i项中以a[i]结尾的最大值,毫无疑问,以a[i]结尾的情况只有两种,一种是ans[i+1]+a[i],一种是a原创 2013-05-06 09:55:15 · 519 阅读 · 0 评论 -
hdu 1069 Monkey and Banana(动态规划)
连续两天没睡好,上午写代码时脑子跟团浆糊一样。中午去补了一觉,神清气爽。这道题算是比较难的吧。每一个箱子都可以产生三组数据,对这些数据按面积从大到小排序。数据处理的时候,如果一个箱子之前所有的箱子都没办法放在这个箱子下面,那就以这个箱子为底,生成一组数据。受习惯的影响, 刚开始我直接把之前最大的数据当成ans[i]的值。。。最后需要从所有ans中选出最大的,还是受习惯的影响,第一遍的时原创 2013-04-07 16:45:55 · 407 阅读 · 0 评论 -
hdu 2571 命运(动态规划)
我开始按照自己的思路做完题,提交WA,后来发现了是因为没有考虑第一行的特殊情况,但是不想重新写代码了,就在原来的基础上各种打补丁,结果反倒浪费了很多时间。就是一个数塔,不过运动的方式多了一点儿。#include#includeint Max(int x,int y){ return x>y?x:y;}int main(){ int i,j,k,m,n; int map原创 2013-04-27 19:37:15 · 472 阅读 · 0 评论 -
hdu 4293 Groups(动态规划)
根据输入可以将整个队列划分成不同的区间,最后去求在这个队列中一共最多可以有多少个不相交的区间。比如说对于第i个人,在其前方有x个人,在其后方有y个人,那么我们可以得到一个[x+1,y]的区间,用mark[x+1][y],记录在这个区间上有多少人。需要注意的是,mark[x+1][y]的值不能大于n-x-y。记录之后,题目就转变成在一条连续的线段上,存在着很多不同的区间,我们需要求出的是最多原创 2013-10-05 16:58:47 · 477 阅读 · 0 评论 -
hdu 3236 Gift Hunting(背包问题)
这道题做的时候觉得很麻烦。思路不是很难,但是一直觉得时间不够用。用最暴力的解法做出来,提交勉强AC。#include#include#includeint dp[501][51][2];struct node{ int x,y; int id;} a[305];int v1,v2,n;int cmp(const void *a,const void *b)原创 2013-10-13 15:41:43 · 592 阅读 · 0 评论 -
hdu 4455 Substrings(动态规划)
昨天训练赛的时候有了一些想法,但是遇上一些问题不知道怎么处理,今天看了别人的题解,才觉得昨天又很严重的消极比赛的感觉。开始看完题目觉得大概是个线段树,想了很久,不明白该怎么建树,然后转而去往DP方面想。当时我想的时候用mark[i]记录两个相同元素之间距离为i的对数,这样可以得到dp[i]=dp[i-1]+n-(i-1)-mark[i],这个想法还是不错的,不过写的时候发现有个问题解决不了原创 2013-09-13 15:03:09 · 622 阅读 · 0 评论 -
hdu 1506 Largest Rectangle in a Histogram(动态规划,很棒的优化)
这道题直接按照一般的思路去算是要超时的,必须经过一定程度的优化。对于a[i],我们需要记录的是他之前和之后最大的连续的值比a[i]大的长度,如果每次都一个个去比对,数据大小是100000,时间复杂度是O(n^2),超时那是必然的。但是其实对于a[i]来说,如果去求后面连续的值,完全没必要一个个去比对,直接看a[i+1]的值就行了。比如说2、3、4、5这个序列,如果我们要看3往后能延伸多长,原创 2013-05-19 16:09:30 · 797 阅读 · 0 评论 -
hdu 4561 连续最大积(水DP)
看了看今天金山居比赛的题,好像就会这一道啊。一个二维二态的DP,用dp[i][0]表示到第i个数成绩为负数的值,dp[[i][1]表示到第i个数成绩为正数的值。需要特别注意的是,如果dp[i-1][0]是0,a[i]是2,那么dp[i][0]还是0;dp[i][1]也一样。刚开始没有注意这一点儿wa了一次,然后看错数据数组开小了又wa了一次。啥都不想说了。#include#inclu原创 2013-05-25 19:25:18 · 1401 阅读 · 0 评论 -
hdu 4123 Bob’s Race(树形DP+单调队列)
昨天做虚拟赛的时候,gby做了一个树形DP,把这道题的数据处理出来,然后问我有没有什么比较快的方法能把计算出一个序列中的最大子区间,这个子区间内的最大值和最小值之差不能大于q。我当时想有没有什么好办法,想了好几种,什么线段树,ST算法之类,但是考虑到速度,感觉还是用单调队列最快。原创 2013-10-30 16:33:34 · 650 阅读 · 0 评论 -
hdu 1508 Alphacode(记忆化搜索)
题目中字符串的长度没有说清楚(也可能是我没看到),提交一直返回wa,改了好久。。。简单的记忆化搜索。需要注意对于0的情况要特别处理。为了方便处理,我的字符串是从1输入的,在字符串的最后我又添加了一个1.#include#include#define N 1000005typedef long long LL;char s[N];int a[N],ln;LL dp[N];LL原创 2013-10-08 19:13:13 · 751 阅读 · 0 评论 -
hdu 1142 A Walk Through the Forest(spfa求最短路+记忆化搜索)
跟hdu 1428题目雷同,算法也雷同。依旧是先用spfa算法算出个点到终点的距离,然后再进行一遍搜索。不过我spfa写得还是突出一个弱。#include#include#includeusing namespace std;#define N 1005#define inf 0x3f3f3f3fint map[N][N],dis[N],dp[N],vis[N];int原创 2013-10-08 17:39:02 · 509 阅读 · 0 评论 -
hdu 1078 FatMouse and Cheese(记忆化搜索)
一道比较直白的记忆化搜索的题目。题目中的k表示横向或者竖直可以前进的距离,不能够拐弯。老鼠的出发点是(1,1)。对于老鼠从当前点能够到达的点,筛选出从这些点到达当前点所能获得的cheese的最大值。如果该点没有值,对该点进行搜索,搜索后的结果记录下来。如果有值,表示该点已经搜索过,只需要直接调用记录的值即可。不需要像一般的搜索那样标记一个点是否遍历过,因为每个点和它的下一个点之原创 2013-10-08 16:33:24 · 692 阅读 · 0 评论