dp
文章平均质量分 63
TommyTT
我擦,要挂科了。
展开
-
poj 3254 Corn Fields(状态压缩dp)
第一次写,注释挺清晰了。注意位运算判断就好了。#include#include#include#include#includeusing namespace std;int dp[20][1<<12];vector s; //每一行所有可能的状态,即相邻位不全为1int can[20]; //用来判断牛是否在1的位置上void debug(i原创 2013-07-03 12:56:28 · 699 阅读 · 2 评论 -
poj 2486 Apple Tree 树形dp
// 好题!mark一下,不会写!参考这里的。。。// http://hi.baidu.com/zyz913614263/item/86f442228b3db8042a0f1c65// 上面的链接解释很详细了,我就不再废话了>_<。#include#include#include#include#includeusing namespace std;vector tree[1原创 2014-01-24 22:41:04 · 860 阅读 · 1 评论 -
hdu 4753 Fishhead’s Little Game (记忆化搜索+状态压缩)
类目类型和 这题很像 点击打开链接记忆化搜索,总分为9分,当前场上剩下的总分减去下一个人能拿到的最多的分数,就是当前玩家能拿到的分数,取最大值就是最优选择。由于最多可能有12条边,所以取边的状态可以用二进制状态压缩表示,10000的数组就足够存下了。#include#include#include#include#includeusing namespace std;b原创 2013-09-21 20:43:05 · 2335 阅读 · 0 评论 -
hdu 4284 TSP问题
注意重边,真坑。裸的TSP#include #include #include#includeusing namespace std;int n,m;int money;int maps[105][105];int dp[17][1<<17];void debug(int x,int y){ printf("dp[%d][%d]=%d\n",x,y,dp[x原创 2013-10-29 14:30:07 · 783 阅读 · 0 评论 -
hdu 4705 树形dp
题意:树上任意三个点不在一条路径上,统计这样的三点集合有多少种。三个点构成的路方案数 S = C(n,3)=n*(n-1)*(n-2)/6用S减去三个点在一条路径上的数目就是答案。枚举中间点作为第二个点,在它的第K棵子树上找一个点作为第一个点,在剩下的,没有枚举过的结点里,找一个点作为第三个点。数目相乘。这样问题就变成了统计结点的子节点问题,简单的树形dp。#include原创 2013-10-19 02:22:40 · 1125 阅读 · 0 评论 -
hdu 1421 搬寝室
/*排序后最佳的选择一定是相邻的*/#include#include#includeusing namespace std;int dp[2005][2005];int a[2005];int main(){ int n,k; while(scanf("%d %d",&n,&k)==2) { for(int i=1;i<=n;i++)原创 2013-07-19 09:44:51 · 608 阅读 · 0 评论 -
hdu 3721 Building Roads 树的直径
题意,移动一条边,使得树的直径最小。首先枚举拆掉的边, 拆掉边后,原图变成2颗树,然后重新连接两颗子树的某两个结点, 那么,此时答案(新树的直径)只有可能有3种情况。1、直径完全在1子树中。2、直径完全在2子树中。3、直径经过了 重新建立的那条边,也就是贯穿了2颗子树。用这3种的最大值更新ans。求树的直径的方法可以通过dfs或者bfs,O(n)时间求出。原创 2013-10-12 20:12:39 · 1129 阅读 · 1 评论 -
hdu 4756 最小生成树
最小生成树建图,然后枚举点,树上dp求出每个点对应的最小值。再统计答案。#include #include#include#include#include#include#includeusing namespace std;#define INF 2000000000#define N 1005double sum;double dis[N][N];dou原创 2013-10-05 23:55:01 · 1097 阅读 · 0 评论 -
hdu 4628 字符串状压dp
字符串长度只有16位,可以用状态压缩保存删除字符串的情况,比如 abeca 10101就代表删除aea字符串首先枚举1~(1然后就是状态压缩dp,对于状态 i 可以用 for(int j=i;j>0;j=(j-1)&i) 来枚举i状态的所有子集 dp[i]= min(dp[i-j]+1,dp[i]) i-j状态必须是回文串#include#include#incl原创 2013-09-19 14:23:14 · 842 阅读 · 0 评论 -
poj 1947 Rebuilding Roads 树形dp
给一颗标准的树(规定好了子父节点),让你剪掉任意条边,得到一颗独立的子树,使得这颗子树的结点数等于p,求最少剪掉几条边。一开始的想法是先求出每个点的孩子结点数,然后枚举剪掉的边,求最小值,然后发现变成了一个排列组合的问题,复杂度是指数级。。。然后看了网上的思路。/*唉,方程又是看了网上的,郁闷死啊*//*dp[i][j]表示以i为结点生成j个结点的子树需要减掉的最少次数*//*原创 2013-07-19 05:16:43 · 566 阅读 · 0 评论 -
uva 10635 Prince and Princess 最长公共子串
最长公共子串,传统算法是O(n*m),我们可以对b中每一个字符在a中找到它出现的位置,构成一个新串,对新串用LIS就得到了最长公共子串nlogn、#include#include#include#includeusing namespace std;templateint bsearch(T c[],int n,T a){ int l=1, r=n; wh原创 2014-01-16 21:40:10 · 806 阅读 · 1 评论 -
poj 2411 状态压缩dp
横的看成11,竖的看成0/1,1.相邻2行之间是否冲突就是看a|b是否全是1。2.同一行是否冲突就是看横着的1的个数是否是奇数。#include#include#include#include#includeusing namespace std;long long dp[15][1<<12];int ok[1<<12];bool isok(int sta){原创 2014-01-16 23:34:31 · 852 阅读 · 0 评论 -
poj 2229 Sumsets 递推
i为奇数时,dp[i]=dp[i-1],i的划分只要在i-1的每个划分前加一个1就够了。i为偶数时,dp[i]=dp[i-1]+dp[i/2],其中的dp[i-1],就是在i-1的每个划分前加一个1,这时候,我们会发现i的划分中含有1的,都在dp[i-1]中计算过了(想想,为什么)。剩下的部分就都是2的倍数,所以提取公因数2计算dp[i/2]就够了。#include#include#i原创 2014-01-18 23:56:38 · 861 阅读 · 0 评论 -
hdu 4597 2013吉林通化邀请赛 Play Game 记忆化搜索
dp[ba][ta][bb][tb]表示a堆牌从下面拿了ba张,从上面拿了ta张。b堆牌从下面拿了bb张,从上面拿了tb张。当前玩家能得到的最大的分数。扩展方式有4种,ba+1,ta+1,bb+1,tb+1,用当前剩下牌的总分减掉它,取最大值,就是当前玩家的最高分。记忆化搜索#include#include#include#include#includeusing names原创 2013-08-24 16:43:29 · 1749 阅读 · 5 评论 -
bzoj 3566: [SHOI2014]概率充电器 树形DP
首先普及一个概率公式 P(A+B)=P(A)+P(B)-P(AB)题意:一些充电元件和导线构成一棵树,充电元件是否能充电有2种情况,1、它自己有qi%的概率充电2、与它相邻的元件通过导线给它充电(导线有p%的概率导通)求最终充了电的元件的期望题解:首先可以将元件能否充电分成3种情况考虑,1、它自己给自己充好了电2、它的儿子方向给它传送了电3、它的父亲方向给它传送了电原创 2014-06-06 15:38:46 · 2230 阅读 · 0 评论 -
ZOJ 3684 Destroy 树的中心
中心节点就是树的中心,2遍dfs求到树的直径,而中心一定在直径上,顺着直径找到中心就够了。然后可以一遍树形DP找到最小值或者二分+判断是否访问到叶子节点。#include #include#include#includeusing namespace std;struct node{ int next; int power; int length原创 2014-05-13 00:02:41 · 988 阅读 · 0 评论 -
poj 1952 BUY LOW, BUY LOWER 最长下降子序列+统计不重复方案数
dp[i]=max(dp[i],dp[j]+1) ja[i]dp[i]表示长度为i的最长下降子序列的长度。r[i]表示长度为i的最长下降子序列的方案数。考虑这样一个问题,比如6 3 9 3,对于两个3,他们数字一样并且dp值也一样,那么r[2]的方案数是没有意义的因为能通过第一个3扩展的也能通过第二个3扩展,所以直接把r[2]=0。对于一次扩展若dp[j]+1==dp[i],则原创 2014-05-17 16:07:53 · 827 阅读 · 0 评论 -
wikioi 1163 访问艺术馆 树形dp
递归建树,由题知该树是一棵二叉树,且除根节点外其他点的度为0或2。dp[i][j]表示来到第i个走廊(还未走过这条走廊)还剩下j时间,能拿到最大的画的数量。dp[i][j]=max(dp[i][j],dp[lson[i]][k]+dp[rson][last_time-k])#include#includeusing namespace std;int dp[200][70原创 2014-05-05 01:30:35 · 1400 阅读 · 0 评论 -
hdu 3339 In Action 最短路+01背包
题意:n个点m条边的无向图,点和边都有权值。 反复从0点出发,求获得大于点总权值一半的边的边权和。因为只有100个点,所以直接floyd求最短路,然后一次01背包,DP[i]表示消耗i的油能摧毁的最多的电力。#include#include#includeusing namespace std;#define INF 0x3f3f3f3fint n,m,a,b,c;in原创 2014-03-10 20:30:10 · 700 阅读 · 0 评论 -
hdu 2844 多重背包的二进制优化
多重背包解。讲多重背包拆分成完全背包和01背包,01背包部分用二进制优化。#include#include#include#include#include#include#include#include#include#include#define eps 1e-12#define INF 0x7fffffff#define maxn 1100using nam原创 2014-01-12 12:21:56 · 861 阅读 · 0 评论 -
poj 3176 Cow Bowling 数塔dp
从下网上推。#include#include#include#include#includeusing namespace std;int a[400][400];int dp[400][400];int main(){ int n; while(scanf("%d",&n)!=EOF) { memset(dp,0,sizeof(dp)原创 2014-01-18 23:33:26 · 831 阅读 · 4 评论 -
cf 219D Choosing Capital for Treeland 树形dp
一遍dfs找到1节点需要装换的边数,然后再一次dfs求得每个点的值,若i能到j,则dp[j]=dp[i]+1,否则dp[j]=dp[i]-1。#include#include#include#include#includeusing namespace std;vector tree[200005];vector dir[200005];int dp[200005];原创 2014-01-20 01:14:14 · 1262 阅读 · 0 评论 -
28.uva 10891 Game of Sum 记忆化dp
这题和上次的通化邀请赛的那题一样,而且还是简化版本。。。那题的题解 请戳这里dp。。。#include#include#include#includeusing namespace std;#define INF 0x3f3f3f3fint dp[105][105];int a[105];int sum,n;int pre_sum[105],next_sum原创 2013-08-29 20:49:00 · 820 阅读 · 0 评论 -
hdu 1078 FatMouse and Cheese 记忆化dp
只能横向或竖向走。。。一次横着竖着最多k步。。。不能转弯的。。。。为毛我的500+ms才跑出来。。。#include#include#includeusing namespace std;int mp[105][105],n,k;int dp[105][105];int dx[105][4]={{0,0,0,0},{-1,1,0,0}};int dy[105][4]={{0,原创 2013-08-18 23:15:07 · 782 阅读 · 0 评论 -
hdu 4568 Hunter bfs建图+TSP状压DP
TSP问题。原创 2013-08-15 15:29:38 · 1620 阅读 · 3 评论 -
hdu 2955 Robberies
题意:Roy 要去抢银行,给你一个Roy 的被抓概率,再给出N个银行的钱和抓捕概率。求能抢的最大的钱数。由概率的知识可知,要求被抓概率,需要先求反面,也就是逃脱的概率,只有逃脱的概率才能连乘。构造dp[i]表示抢到i数量的钱最大的逃脱概率。转移方程 dp[i]=max(dp[i],dp[i-cost[j]]*p[j]); cost[j]代表第j个银行的钱,p[j]代表第j个银原创 2013-06-18 00:14:30 · 596 阅读 · 0 评论 -
poj 2378 树型dp
和poj1655那道求树的重心基本上一样的,代码也没多大改动。详情请见#include#include#include#includeusing namespace std;#define MAXN 100000int N;vector node[20005];int num[MAXN]; //num[i]为以i结点为根的树的所有结点数。int dp[MAX原创 2013-07-15 08:15:36 · 940 阅读 · 0 评论 -
poj 1191 棋盘分割(记忆化dp+递归)
根据这2个公式可以 得到 O^2 = sum(x1^2 + x2^2 + x3^2 +...xi^2)/n - 平均值^2所以我们就是要使得总分的平方和尽量小……详见black book ^_^G++提交的时候记得把.3lf改成.3f#include#include#include#includeusing namespace std;double sum[9][9原创 2013-07-12 23:49:54 · 602 阅读 · 0 评论 -
poj 1655 Balancing Act(求树的重心)
在一棵树中,去掉一个点,使得剩下的每一颗树的结点数最多的那颗树,结点数最少。具体解法看注释./* 定义dp[i]为去掉i结点,剩下的树里,结点最多的那颗树的结点数。 可分为2类情况。 1、由于i结点的儿子结点都成了一棵树的根节点,所以dp[i] = (i的每个儿子所拥有的结点数,的最大值)。 2、而另一种情况就是剩下的那棵树,所以dp[i] = N-原创 2013-07-11 14:39:44 · 1287 阅读 · 0 评论 -
poj 3311 Hie with the Pie(状压dp)
给你一张图,要求遍历所有点且使得总路径最短(最后要回到起始点0)1、首先用一遍floyd找到所有2点之间的最短距离。2、状态压缩dp 【 dp[i][j]表示当前状态为j,终点为i的路径长度 】 1)、用n+1为二进制串表示n+1个地点的经过信息,1为经过,0为未经过 (例如n=6, 经过0,3,5点,状态表示为0101001)2)、状态转移方程 dp[i][j]=min(dp[原创 2013-07-04 14:42:27 · 503 阅读 · 0 评论 -
UVA 10590(完全背包,整数拆分+大数加法)
大数加法一位位存效率很低会TLE,我是10亿10亿存的。#include#include#include#include#include#includeusing namespace std;class bign{public: int a[10]; int leng; void print(); bign () {leng=0;memset(a,0,sizeof(原创 2013-07-05 16:34:50 · 1203 阅读 · 1 评论 -
poj 1160 Post Office(DP简单题)
给n个村子建p个邮局,求最佳的建设方案使得每个村子到最近的邮局的距离和最短,输出最短距离。首先递推求出n个村子建1个邮局的最佳方案,画下图很容易理解。再递推求解多个邮局的最佳方案,具体的看注释吧。/*//k从1枚举到i-1就够了dp[i][j]=min(dp[i][j],dp[k][j-1]+sum[k+1][i]);这个画下图很好推出来的。sum[i][j]=sum[i][原创 2013-07-09 11:45:59 · 802 阅读 · 0 评论 -
poj 3017 Cut the Sequence(DP+单调队列)
题意,给定一个序列,让你把它分割成N个子串,使得每个子串的和DP解:方程为 DP[i]=max(DP[i],DP[p-1]+ max(a[p]~~a[i]) ),P为当前分割的位置,i为当前元素下标。 Sum( a[p]~~a[i] )要满足而p要从p一直枚举到j,因为这之间任意一个位置作为分割点都有可能产生最优解。#include#include#includeusing na原创 2013-07-09 09:05:11 · 706 阅读 · 0 评论 -
hdu(1520) Anniversary party(树形dp)
树形dp入门题,dp[i][1] 表示选择i结点的最大值,dp[i][0]表示不选i结点的最大值。则方程为 dp[i][1] += dp[i的所有孩子][0] (依题意,i选了,i的孩子就一定不能选) dp[i][0] += max(dp[i的所有孩子][0],dp[i的所有孩子][1]) (i不选,则他的孩子可以选,也可以不选,我们选择二者的最大值)存图的时候我用了一个vecto原创 2013-07-05 21:30:31 · 511 阅读 · 0 评论 -
hdu 2993 MAX Average Problem 斜率优化DP
详见,算法合集之《浅谈数形结合思想在信息学竞赛中的应用》。#include#include#includeusing namespace std;double sum[100010];int q[100010];bool judge(int i,int j,int k){ // if((sum[j]-sum[i])/(j-i)>=(sum[k]-sum[i])/(k-i))原创 2013-07-14 23:16:24 · 646 阅读 · 0 评论 -
hdu 1300 Pearls DP
方程很好推,n^2过的。#include#include#includeusing namespace std;#define maxn 105int a[maxn],p[maxn],sum[maxn];int dp[maxn];int main(){ int t,n; scanf("%d",&t); while(t--) { s原创 2013-07-16 09:52:13 · 726 阅读 · 0 评论 -
poj 3709 K-Anonymous Sequence 斜率优化dp
斜率优化dp原创 2013-07-16 16:58:41 · 857 阅读 · 0 评论 -
hdu 1011 Starship Troopers 树形dp
树形dpdp[i][j]表示 i房间还有j个士兵能获得的最大价值。当士兵数为0个的时候,就不能继续往下走了。但当大部队遇到中途的bug为0的房间的时候,就可以不留士兵获取价值。#include#include#include#includeusing namespace std;vector tree[105];int sum[105],val[105];int dp原创 2013-08-20 09:38:24 · 647 阅读 · 0 评论 -
hdu 4487 概率dp Maximum Random Walk
总共有n轮走法,每次可以向左向右或不动。 求到达最右端的期望#include#include#include#includeusing namespace std;double l,r,m;int n;double dp[103][222][222];void solve(){ m=1-r-l; dp[0][100][100]=1; for(int i原创 2013-08-13 09:16:40 · 883 阅读 · 0 评论 -
poj 3744 Scout YYF I 概率dp
题意:有N颗雷,位置为a[0]-a[n-1] ,p概率走一步,1-p概率走两步,求到达终点的概率(也就是安全跨过最后一颗雷)分段求解,使每段包含一颗雷。分别求每段被炸死的概率,然后用1减,就是安全通过的概率。把每段安全的概率乘起来,就是答案。dp[i]=p*dp[i-1]+(1-p)*dp[i-2]是到达i点的概率,i点有雷的话,那就是被炸死的概率了。 构造矩阵,和斐波原创 2013-08-13 17:04:05 · 672 阅读 · 0 评论