随笔分类 -  动态规划

ACM重点
摘要:我设计的状态及转移过程dp[i][j]代表前i分钟最多走j次所能获得苹果的最大值则可以由 前i-1分钟最多走j次 前i-1分钟最多走j-1次 这两个状态转移过来注意,第二种的转移第j次可以选择走或者不走。因为是最多走j次跟以前做过的一个树形DP神似View Code #include<cstdio>#include<cstring>int dp[1010][35];int num[1010];int max(int a,int b){ return a>b?a:b;}int main(){ int T,W,i,j; while(scanf("%d%d&q 阅读全文
posted @ 2012-04-03 22:55 Because Of You 阅读(1323) 评论(2) 推荐(0)
摘要:2A的题,因为注释没去完。。。。。。题意:给你n个数,求长度大于2的且相邻数字绝对值差不超过H的序列的个数很容易想到一个朴素的O(n^2)DPdp[i]=sigma(dp[j],abs(val[i]-val[j])<=H)由于DP转移过程是求和的操作,所以可以用树状数组来优化求和操作进一步转换:val[i]-H<=val[j]<=val[i]+H,所以每次把val[i]-H到val[i]+H之间的树状数组中的数求和 假设和为pre,dp[i]=pre+1;表示以i结尾的序列的个数序列长度>=1,求和后再把dp[i]放进树状数组即可最后的答案还要减掉n,取出长度为1的序列 阅读全文
posted @ 2012-03-28 11:21 Because Of You 阅读(611) 评论(0) 推荐(0)
摘要:判断1*2的砖块去填m*n的矩形总共的摆放方案dp[i][j]表示当前行状态为j时的总共的摆放方案先枚举上一层i的状态,如果存在某状态,就把还空的位置用竖的砖块插入,插满后,记录下当前i+1行的状态然后在i+1行暴力枚举所有可能摆放方案,这个状态数再叠加上同一行上一个的状态(没有摆放横砖块之前)总数最后的答案就是 dp[h][(1<<w)-1]即DP到最后一行,且摆满#include<stdio.h>#include<string.h>int h,w;__int64 dp[15][2050];void dfs2(int row,int state,int c 阅读全文
posted @ 2012-03-25 21:59 Because Of You 阅读(857) 评论(0) 推荐(0)
摘要:http://www.acdream.tk/problem.php?cid=1001&pid=1dp[i] 表示匹配前i个字符的最大权值View Code #include<stdio.h>#include<string.h>#include<queue>using namespace std;class trie{public : int num; trie* child[27]; trie() { num=0; memset(child,0,sizeof(child)); }}root;void insert(char *s,int... 阅读全文
posted @ 2012-03-23 21:11 Because Of You 阅读(377) 评论(0) 推荐(0)
摘要:dp[i][j]表示一边亮i个洞,一边亮j个洞到达成目标还需的天数显然dp[i][j](i>=m,j>=m)=0;dp[i][j]和dp[i+a][j+b]形成递推关系所以需要枚举i,j以及a、b的所有组合数复杂度为O(n^4)注意每个灯亮与不亮都是独立的四个for循环View Code #include<cstdio>#include<cstring>const int maxn = 55 ;double dp[maxn][maxn];double c[maxn][maxn];double mulp[maxn];double mul_p[maxn];dou 阅读全文
posted @ 2012-03-22 19:29 Because Of You 阅读(579) 评论(0) 推荐(0)
摘要:One Person GameTime Limit:1 Second Memory Limit:32768 KB Special JudgeThere is a very simple and interesting one-person game. You have 3 dice, namelyDie1,Die2andDie3.Die1hasK1faces.Die2hasK2faces.Die3hasK3faces. All the dice are fair dice, so the probability of rolling each value, 1 toK1,K2,K3is exa 阅读全文
posted @ 2012-03-21 21:28 Because Of You 阅读(465) 评论(0) 推荐(0)
摘要:http://www.codeforces.com/problemset/problem/165/E蛮巧妙的,关键是以前做的少,mark一下View Code #include<cstdio>#include<cstring>int f[5000010],a[1000010];int main(){ int n,i,j,k; scanf("%d",&n); memset(f,0,sizeof(f)); for(i=1;i<=n;i++) { scanf("%d",... 阅读全文
posted @ 2012-03-18 01:06 Because Of You 阅读(400) 评论(0) 推荐(0)
摘要:DP[i][j]表示以i为根节点的子树总共使j个客户收到信息的最大报酬dp[u][j+k]=max(dp[u][j+k],dp[u][j]+dp[v][k]-w) u是v的父节点,w为u、v的边权View Code #include<cstdio>#include<cstring>#define max(a,b) a>b?a:bconst int INF = 1000000000;const int maxn = 3010;int head[maxn],dp[maxn][maxn],n,m;int num[maxn];struct EDGE{ int v,w,ne 阅读全文
posted @ 2012-03-13 18:19 Because Of You 阅读(340) 评论(0) 推荐(0)
摘要:同poj 3342http://www.cnblogs.com/wuyiqi/archive/2012/03/08/2385680.htmlView Code #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>#include<string>#include<map>using namespace std;#define max(a,b) a>b?a:bconst int maxn = 阅读全文
posted @ 2012-03-11 00:09 Because Of You 阅读(327) 评论(0) 推荐(0)
摘要:DP过程注意:对于每个矛盾关系,从老板向员工连一条边dp[i][0]表示不取i的最大值,可以由两个状态转移而来dp[i][0]+=sigma[ max(dp[j][0],dp[j][1])],j为儿子,即儿子取或不取都可以dp[i][1]表示取i的最大值,初始值赋为1,那么儿子节点就不能取了,所以dp[i][1]=sigma(dp[j][0]);判断方案是否唯一观察状态转移的过程可知:dp[i][0]是由dp[j][0],dp[j][1]两个状态过来的,所以当dp[j][0]==dp[j][1]时,方案不唯一,即子节点选与不选都可以但是注意前提是dp[i][0]更优与dp[i][1],即i这个 阅读全文
posted @ 2012-03-08 19:22 Because Of You 阅读(1066) 评论(0) 推荐(0)
摘要:好猛的一道题目,做到吐血,最后发现有一组数据栈溢出了,就一组!!!算了,想法还是最重要的参考这里,可以和我的文章结合起来看http://www.cppblog.com/Yuan/archive/2010/09/06/125962.html?opt=admin首先明确一点,由于是两点之间的一条路径,所以不可能出现下面的情况即不可能出现三叉路口,出现三叉的就不是两点间的路径了所以只能是下面两种情况1、 以u为根时,路径分布在u的两棵子树中,一棵子树中的长度为a,另一棵为b=L-2-a,(图中红色的路径部分除外)2、 只延伸出一条路径到一棵子树中所以在v这棵子树中有L-1长度的路径存在。我们先假设整 阅读全文
posted @ 2012-03-07 20:48 Because Of You 阅读(477) 评论(0) 推荐(0)
摘要:状态转移:dp[state][i]=sigma(dp[state'][i-1]);state和state'都是合法状态更多的注释在代码中View Code #include<cstdio>#include<cstring>int dp[13][1<<13];int cur[15];int state[1<<13];int m,n,tot;const int mod = 100000000;bool ok(int state){ if(state&(state<<1)) return false; return 阅读全文
posted @ 2012-02-18 21:08 Because Of You 阅读(288) 评论(0) 推荐(0)
摘要:RelocationTime Limit:1000MSMemory Limit:65536KTotal Submissions:823Accepted:326DescriptionEmma and Eric are moving to their new house they bought after returning from their honeymoon. Fortunately, they have a few friends helping them relocate. To move the furniture, they only have two compact cars, 阅读全文
posted @ 2012-02-15 14:19 Because Of You 阅读(777) 评论(0) 推荐(0)
摘要:dp[i][j]表示快的人走到i,慢的人走到j时的最小路程(j<i)从左到右对于每个点要么给走的快的人,要么给走的慢的人初始化dp[i][j]=INF状态转移方程:f[i+1][i]=min{f[i+1][i],f[i][j]+dis[j][i+1]}此前为f[i][j],当前点i+1分配给jf[i+1][j]=min{f[i+1][j],f[i][j]+dis[i][i+1]}此前为f[i][j],当前点i+1分配给i其中0<=j<i最后结果为min(f[n][i]+dis(i,n))其中i<nView Code #include<cstdio>#incl 阅读全文
posted @ 2012-01-29 18:08 Because Of You 阅读(830) 评论(0) 推荐(1)
摘要:很典型的树形DP,自己也理解了好久,感觉自己好水哦。。。。。。。。。。。。。。。。。。。。。。。。。所以讲得清楚一点,以后回忆起来也快题意:一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值我们把背包的思想用到这里来,做的步数相当于背包的容量,点上的权值相当于价值,给定一定的背包容量,求最多能装进背包的价值设dp[0][s][j]表示从s(当前根节点)出发,走 j 步,回到s所能获得的最大权值 dp[1][s][j]表示从s(当前根节点)出发,走j步,不回到s所能获得的最大权值现在我们就可以分配背包容量了:父节点与子节点分配背包容量,从而设计出状态 阅读全文
posted @ 2012-01-09 08:11 Because Of You 阅读(3458) 评论(3) 推荐(1)
摘要:把最贵的先留着最后再买View Code #include<stdio.h>#include<string.h>int dp[1010];int p[1010];int max(int a,int b){ return a>b?a:b;}int main(){ int n,m,i,j,pos; while(scanf("%d",&n),n) { int Max=0; for(i=1;i<=n;i++) { scanf("%d",&p[i]); if(p[i]>Max) ... 阅读全文
posted @ 2012-01-09 02:28 Because Of You 阅读(316) 评论(0) 推荐(0)
摘要:分析:典型dp,状态转移方程dp[i][j]=dp[i-1][j-1]+dp[i][j-i];dp[i][j]表示i辆卡车装j台电脑的方法数。例如:8台电脑3台车卡车1卡车2卡车3dp[3,8]=dp[2,7]+dp[3,5]第一类611卡车3只放一台电脑,运法总数相当于2台卡车运7台电脑dp[2,7]。521431第二类422每台车有一台以上电脑,运法总数相当于3台车运5台电脑dp[3,5]332c++View Code #include<stdio.h>#include<string.h>__int64 dp[210][210];void init(){ int i 阅读全文
posted @ 2011-12-19 14:42 Because Of You 阅读(478) 评论(0) 推荐(0)
摘要:http://www.cnblogs.com/zjh10/articles/2032294.html这个题目是说 每个点有权值,有些点的得到需要先得到某点,问你选M个点能够得到的最大值很明显是有依赖的背包,而且应该是有依赖中有依赖(虽然我觉得题目并没有很明确地说)~这样的话 我们就构建dp[i][j],i为i号点,j为它选了里面的几个点。。。。。这样的话 我们就发现其实是个树,点的值取决于子点的选法。方程dp[k][j]=max(dp[k][j],dp[k][j-kk]+dp[t[k][i]][kk])表示在第i个k的子点中选kk个点加上目前k号点选j-kk个点与直接在k号点选j个点谁更优。。 阅读全文
posted @ 2011-12-19 13:34 Because Of You 阅读(2492) 评论(7) 推荐(1)
摘要:转自http://www.cppblog.com/baby-fly/archive/2010/08/03/122027.aspx?opt=admin很显然是动态规划。dp[i]表示前i个数有多少个有效的子序列。那么 dp[i]=dp[i-1]+A。 A是前面i-1个数中,与i的差值不超过d的以该数结尾的有效的子序列的个数 的和。我们可以用另外一个数组sub[i]表示以i结尾的有效的子序列的个数。 dp与sub的不同之处是dp中的子序列不一定是以第i个数结尾的。sub[i]= sigma sub[k] ,( abs(numk],num[i])<=d )。 由于求sub的时间复杂度为O(n^ 阅读全文
posted @ 2011-12-19 06:19 Because Of You 阅读(394) 评论(0) 推荐(0)
摘要:我决定:以后每一场codeforces我都将进行总结,尽量在赛后把题目AK(*_*),水平有限,只能说尽量。难得有一场CF的比赛在白天开始,于是我准时的守候在电脑前准备打一场CF,哈哈a题b题很快过了,c题卡了一下,原因是在poj做过类似的一道题,http://www.cnblogs.com/wuyiqi/archive/2011/09/20/2182986.html但是这道题目只需要求有几个区间能被其他区间完全覆盖,并不需要求每个区间分别能被几个区间覆盖,这是本质差别对于这道题,只需要排个序(没必要用树状数组)x递增,y递减所以后面的x肯定大于等于前面的x,现在只需要比较y即可,如果y小于m 阅读全文
posted @ 2011-12-19 00:03 Because Of You 阅读(419) 评论(0) 推荐(0)