![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
动态规划
文章平均质量分 72
查尔斯欢
这个作者很懒,什么都没留下…
展开
-
hdu5188 二分 or 背包
题目关键在于,对于时间最少的方法的方法,一定按照题目最早可以开始做的时间的顺序做,即按照l-t的从小到大顺序来做。不妨假设1的开始时间小于2,那么一旦先做2,很明显从做完上件题目后的等待时间加长,因此可以得出最优解一定按照l-t的顺序做。然后就是两种方法了,一种背包,一种二分,背包是求出了每个时间的最优值,而二分加dfs只是不断验证是否可行再二分的过程,事实证明,后者省去很多时间。附代原创 2015-03-16 15:51:00 · 551 阅读 · 0 评论 -
hdu4628 状态压缩搜索or状态dp
题意很简单,让求一个个去回文串最少要花费几步才能消完。首先贪心肯定是不行的,例如abb原创 2014-07-22 14:45:15 · 725 阅读 · 0 评论 -
poj2411 状态压缩dp
一道经典状态压缩dp题目。题意很明确,让用1*2或2*1的小方格铺满原创 2014-07-22 09:46:45 · 874 阅读 · 0 评论 -
zoj3755 状态压缩dp
很久没有1A了~爽~题目也是很常规的状态压缩题目,原创 2014-07-21 11:59:53 · 723 阅读 · 0 评论 -
poj3254 状态压缩dp
状态压缩基础题目,注意取模,水水就过了代码:#include #include #include using namespace std;int n,m;int map[15];int dp[15][1000];int status[1000];int cnt=0;bool ok(int i){ if (i&(i<<1)) return f原创 2014-07-21 15:45:53 · 667 阅读 · 0 评论 -
poj1185 状态dp
状态dp经典题目。这种状态dp,原创 2014-07-20 12:36:33 · 686 阅读 · 0 评论 -
poj1948 二维背包
携程的第二场第二题,比赛时被原创 2014-04-12 11:42:07 · 874 阅读 · 0 评论 -
hdu4745 最长回文子序列
这个题目其实就是让求最长回文zi原创 2014-04-21 13:55:57 · 1060 阅读 · 0 评论 -
hdu4521 线段树or变形LIS
题意很简单,让求序列中两个数id相差为d原创 2014-05-05 09:20:03 · 706 阅读 · 0 评论 -
hdu4734 动态规划(数位dp)
数位dp的题目,,题意很简单原创 2014-05-05 09:01:45 · 665 阅读 · 0 评论 -
spoj 3408 动态规划
最长公共子序列的变形,数据太强了,略微一点处理不好就超时,被折磨了好几天。。。题目说,对于两个字符串,对字符串求最长公共子序列,且子序列必须是由两个字符串中长度均大于等于K的字串组成。思路很好想,类似最长公共子序列,对两个序列进行匹配,记录匹配的子串的连续长度,长度大于等于K证明是可用子串,如果可用串长度大于k,有两种情况,当前的串取最长加上之前的最大值,和当前的串取k和最大值,例如对于长原创 2014-03-19 22:08:22 · 799 阅读 · 0 评论 -
spoj2815 线段树+离散化+动态规划
题意很明确,让求序列中上升长度等于k的子序列个数。这里采用线段树进行求解,最多维护50棵线段树,每一棵线段树记录长度为i的序列个数。输入数据后进行离散化,这里注意不能使用map,会超时,只能说spoj的服务器太渣渣了。离散化之后就可以对线段树读入数据,每一个数据读入后,依次维护以当前节点结尾长度从1到k的序列长度的个数,这个值记录在对应线段树的对应节点上。以v为结尾长度为k的序列数+=以v原创 2014-03-29 13:10:59 · 747 阅读 · 0 评论 -
hdu4632 区间dp
好久没写区间dp了,手好生的说。注意原创 2014-08-03 15:19:01 · 638 阅读 · 0 评论 -
hdu4901 背包
枚举分界线,将分界线上的元素强行划分原创 2014-08-03 09:27:40 · 621 阅读 · 0 评论 -
hdu5115 区间dp
和北京的那道题好像,可惜还是没能在比赛中做出来。这个题目可以这样,将n个人分配到座位上,就是求1~n的全排列中符合题意的个数,其中1~n的编号就是他们坐的顺序,先枚举最后一个坐的人的座位编号,然后剩余的人(即编号)分成两部分,一部分在第一个人的左边,一个人在第一个人的右边,这样对于左右两边又是一次全新的分配(左右两边分配到的的编号可能不连续,但是他们有先后顺序即可确定坐的次序,无非是左边坐完右原创 2014-12-28 17:39:39 · 745 阅读 · 0 评论 -
vijos 1193 dp
每一行的状态由之前两行决定,dp[i][t][k]表示第i行状态为k,下一行状态为t时的种数,然后dp一遍即可。代码:#include #include #include using namespace std;int a[10010];int dp[10010][2][2]; //1下一行还需要一个1,0下一行不需要1int main(){ int n;原创 2014-12-15 20:22:29 · 677 阅读 · 0 评论 -
NOIP2014 子矩阵
状压dp水题。#include #include #include using namespace std;int mp[20][20];int dp[20000][20][20];int n,m,r,c;int sta[20000];int v[20000][20][20];int vv[20000][20];int sc;int abs(int a){原创 2014-12-15 17:02:44 · 1784 阅读 · 0 评论 -
hdu5115 北京现场赛D
比赛时一直想贪心,其实就是个弱到爆的区间dp。#include #include #include using namespace std;int dp[222][222];int a[222];int n;int min(int a,int b){ return a<b?a:b;}int solve(int l,int r){ if (dp[l]原创 2014-11-29 14:45:21 · 1075 阅读 · 0 评论 -
hdu5064 dp
用dp[i][k]表示以i和k两个节点作为结尾的能形成的符合题意的串的长度。原创 2014-10-16 20:44:16 · 679 阅读 · 0 评论 -
hdu4778 状态压缩dp+博弈
好难的一道题目,可能跟自己以前很少做博弈有关吧。题意很好理解,两者都在最优策略下取包裹,问最后得到的原创 2014-09-03 21:01:20 · 1542 阅读 · 0 评论 -
hdu5009 dp
找到每个位置每种颜色数向前最多延伸到哪个位置,原创 2014-09-15 19:43:05 · 682 阅读 · 0 评论 -
hdu5001 dp
核心思想就一句话,看代码#include #include #include #include using namespace std;double dp[10010][55];int n,m,d;vector mp[55];//无论怎么走,最后肯定停在某个点上,经过某条路径停在某个点上总共两种方式,要么经过x,要么不经过x,不经过x停在//其他点上的概率和就是不经过原创 2014-09-15 18:35:08 · 597 阅读 · 0 评论 -
hdu4961 dp
预处理一下所有因子,正反各跑一遍,记录下即可。原创 2014-08-29 10:50:53 · 584 阅读 · 0 评论 -
zoj3812 状压dp
用一个二进制数表示能表示的所有原创 2014-09-11 21:48:47 · 624 阅读 · 0 评论 -
状态dp小结 (hdu4804 hdu4856 hdu3681 poj3311 hdu3001 cf453B hdu4906 zoj3802)
hdu4804会的人说是水题,不会的是原创 2014-07-26 11:14:22 · 1112 阅读 · 1 评论 -
spoj2817 线段树+离散化+动态规划
题目和2815差不多,只不过对于两个完全相同的序列,即使相对位置不完全相同,那也不能算作两个序列,问这样的序列的个数。相较于上一题,这道题加入一个mark数组记录相同的一个数在之前是否出现过,如果出现过,那么对于以其为结尾的长度为k的序列,以当前位置的数为结尾肯定包含了以之前的数为结尾的序列,即例如1 2 5 4 5,那么第一个出现的5长度为3的序列为1 2 5,第二次出现的5长度为3的序列原创 2014-03-29 17:20:51 · 669 阅读 · 0 评论 -
spoj 130 动态规划
第一次写这种类型的动态规划,一开始想离散化之后用背包,算了下时间复杂度,果断放弃了,百度了下解题思路,不得不说挺神奇的。题目让取一些不重合的区间使获得的总收益最大,那么,可以对所有区间按照结束时间进行排序,这样能确定算后面的任意一个区间时,其开始时间之前的所有结果已经算出,然后,对于第i个,开始时间为st,结束时间为et的区间,结束时间为et之前的所有区间都已经算过,那么到et的最大值,要么为原创 2014-03-28 22:28:56 · 802 阅读 · 0 评论 -
poj2955
区间dp看了刘汝佳的书,恰巧发现了这么一道题,抱着虐菜的心态,反被虐了一下午,自己还是太渣渣。题目类型还是区间dp,对于一个一维序列,通过从中划分为两个,四个。。。。个序列,知道剩余一个括号或者没有括号,一个括号则不是规则的,删掉,返回1,空的序列则是规则的,返回0,通过这样不断递归得到最优解。关于递归方程式,借用刘汝佳的书里的状态划分:1):如果序列式形如(s‘)或【s'】,则只原创 2014-02-25 22:12:45 · 1440 阅读 · 0 评论 -
uva10003
区间dp人生中首次写区间dp的题目,关键是写之前根本不知道区间dp这回事,结果就是浪费了一下午时间也没写出来。题目让在一段区间上,给定需要分割的点和一个价值计算方法,问最小价值。开始时总纠结于每一刀的状态,其实压根不用如此,所有需要切割的点都已经知道,只要切完就行,何必纠结于第几刀的问题。按照区间dp的思想,假设有c【1】到c【10】,十个切割点,那么,设dp【i】【t】为i到t已经切好的原创 2014-02-25 13:29:46 · 721 阅读 · 0 评论 -
hdu2185
简单dp#include using namespace std;int dp[1005][16][16];int main(){ int w[1005]; int b[1005]; int sum=1; while (cin>>w[sum]>>b[sum]) sum++; memset(dp,0,sizeof(dp原创 2013-11-16 23:13:48 · 1210 阅读 · 1 评论 -
poj3260
经典背包啊。。。思路很清晰,买家多重背包加卖家完全背包,问题的关键是,所需开的数组的上限无法确定,做过类似的题目开了100倍背包容量过了,这题开一百倍就10^6级别,用背包的话肯定超时,本人亲试。然后改到20W的时候A掉了,百度了下证明,大神果然屌。。。证明:上限为T+maxV^2假设顾客给点钱超过T+maxv^2,则店家找的钱肯定超过maxv^2,钱币数n超过maxv。设店家原创 2014-02-21 22:32:53 · 941 阅读 · 0 评论 -
poj1742
好坑的题目。。。非正常的背包题目仅要求计数,不要求求最大值最小值什么的,这点是这道题目的突破点。刚开始以为是普通的多重背包,直接进行二进制优化多重背包,果断TLE,然后开始各种优化,结果各种悲剧,一直在超时。后来百度大神代码,发现了这种背包写法,这种背包写法弊端很明显,只能确定某个值能否达到,但是由于过程中对每一个硬币,是否选用并非取决于是否能得到局部最优解,而是是否能达到某个值,而多原创 2014-02-20 21:57:01 · 1064 阅读 · 1 评论 -
hdu2191
多重背包两种思路一:将每件物品,无论是否相同,都作为独立的一件进行01背包,时间消耗较大。二:转化为二进制,如5分解为1+2+3,,1分解为1+2+4+6,如此一来,对任意整数n,保证了0~n内均可由这些数组合而成,对任意物品,可以保证分解之后不影响取的所有状态,而转化以后,将n的数量转化为logn,大大降低了时间消耗。一:#include using namespace原创 2013-12-17 23:10:39 · 782 阅读 · 0 评论 -
hdu1011
树形dp背包对任一节点,取得最大值相当于在确定根节点消耗之后对所有子树进行01背包,获得1~m每个状态的最大值,然后向上递归,直至找到根节点,此时求得的最大值即为所求状态转移方程:dp[i][t]=max(dp[i][t],dp[i][k]+dp[son[i]][t-k])(k=0,1,2......)#include using namespace std;int map[1原创 2013-12-17 23:05:20 · 733 阅读 · 0 评论 -
hdu1081
简单DP按行压缩求最大和子序列#include using namespace std;int map[105][105];int dp[105][105];int main(){ int n; while (scanf("%d",&n)!=EOF) { memset (map,0,sizeof(map)); mems原创 2013-11-30 17:24:31 · 706 阅读 · 0 评论 -
hdu1502
简单DP将串分成三种情况:末尾为A,末尾为B,末尾为C。则dp[i][t][k]=dp[i-1][t][k]+dp[i][t-1][k]+dp[i][t][k-1]。#include #include using namespace std;int dp[65][65][65][11];const int INF=100000000;int main(){ dp[原创 2013-11-27 22:25:02 · 897 阅读 · 0 评论 -
hdu2182
简单DP#include using namespace std;int main(){ int T; cin>>T; while (T--) { int N,A,B,K; cin>>N>>A>>B>>K; int dp[105][105]; int p[105]; mem原创 2013-11-13 22:47:35 · 873 阅读 · 0 评论 -
hdu1114
简单dp#include using namespace std;int dp[10005];int main(){ int v[505]; int w[505]; int e,f; int T; cin>>T; while (T--) { cin>>e>>f; memset(v,0,size原创 2013-11-16 23:12:23 · 724 阅读 · 0 评论 -
hdu2089
简单数位dpdp【i】【t】记录长度为i位首位为t的满足题意的数字个数,dp时很简单,如果首位为6则次位不能为2,若首位为4则直接等于0。统计时注意高位部分若含有62或4则直接跳出,在此之前统计的结果作为结果,否则继续统计。#include #include using namespace std;int dp[10][10];int main(){ for (原创 2014-02-27 10:41:24 · 694 阅读 · 0 评论 -
hdu3652
数位dp分析题目需求,需要求数字中含有13且能被13整除的数字,是否含有13很容易判断,数位dp时记录一下是否含有13即可,若含有,则不论首位,如不含,则首位为1且次位为3的才满足题意,但是确定能否被13整除就优点麻烦了,按照一般数位dp的方法,由于从高位到低位进行统计,并不知道某个数能否被13整除,无法确定该数字是否满足题意。再分析,对任意一个数字对13取余均只有13中情况,那么在统计时原创 2014-02-27 10:34:46 · 994 阅读 · 0 评论