dp
文章平均质量分 63
TommyTT
我擦,要挂科了。
展开
-
poj 3254 Corn Fields(状态压缩dp)
第一次写,注释挺清晰了。 注意位运算判断就好了。 #include #include #include #include #include using namespace std; int dp[20][1<<12]; vector s; //每一行所有可能的状态,即相邻位不全为1 int can[20]; //用来判断牛是否在1的位置上 void debug(i原创 2013-07-03 12:56:28 · 701 阅读 · 2 评论 -
poj 2486 Apple Tree 树形dp
// 好题!mark一下,不会写!参考这里的。。。 // http://hi.baidu.com/zyz913614263/item/86f442228b3db8042a0f1c65 // 上面的链接解释很详细了,我就不再废话了>_<。 #include #include #include #include #include using namespace std; vector tree[1原创 2014-01-24 22:41:04 · 865 阅读 · 1 评论 -
hdu 4753 Fishhead’s Little Game (记忆化搜索+状态压缩)
类目类型和 这题很像 点击打开链接 记忆化搜索,总分为9分,当前场上剩下的总分减去下一个人能拿到的最多的分数,就是当前玩家能拿到的分数,取最大值就是最优选择。 由于最多可能有12条边,所以取边的状态可以用二进制状态压缩表示,10000的数组就足够存下了。 #include #include #include #include #include using namespace std; b原创 2013-09-21 20:43:05 · 2349 阅读 · 0 评论 -
hdu 4284 TSP问题
注意重边,真坑。 裸的TSP #include #include #include #include using 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 · 785 阅读 · 0 评论 -
hdu 4705 树形dp
题意:树上任意三个点不在一条路径上,统计这样的三点集合有多少种。 三个点构成的路方案数 S = C(n,3)=n*(n-1)*(n-2)/6 用S减去三个点在一条路径上的数目就是答案。 枚举中间点作为第二个点,在它的第K棵子树上找一个点作为第一个点,在剩下的,没有枚举过的结点里,找一个点作为第三个点。数目相乘。 这样问题就变成了统计结点的子节点问题,简单的树形dp。 #include原创 2013-10-19 02:22:40 · 1128 阅读 · 0 评论 -
hdu 1421 搬寝室
/*排序后最佳的选择一定是相邻的*/ #include #include #include using 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 · 609 阅读 · 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 · 1130 阅读 · 1 评论 -
hdu 4756 最小生成树
最小生成树建图,然后枚举点,树上dp求出每个点对应的最小值。再统计答案。 #include #include #include #include #include #include #include using namespace std; #define INF 2000000000 #define N 1005 double sum; double dis[N][N]; dou原创 2013-10-05 23:55:01 · 1100 阅读 · 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 · 843 阅读 · 0 评论 -
poj 1947 Rebuilding Roads 树形dp
给一颗标准的树(规定好了子父节点),让你剪掉任意条边,得到一颗独立的子树,使得这颗子树的结点数等于p,求最少剪掉几条边。 一开始的想法是先求出每个点的孩子结点数,然后枚举剪掉的边,求最小值,然后发现变成了一个排列组合的问题,复杂度是指数级。。。 然后看了网上的思路。 /*唉,方程又是看了网上的,郁闷死啊*/ /*dp[i][j]表示以i为结点生成j个结点的子树需要减掉的最少次数*/ /*原创 2013-07-19 05:16:43 · 568 阅读 · 0 评论 -
uva 10635 Prince and Princess 最长公共子串
最长公共子串,传统算法是O(n*m),我们可以对b中每一个字符在a中找到它出现的位置,构成一个新串,对新串用LIS就得到了最长公共子串nlogn、 #include #include #include #include using namespace std; template int bsearch(T c[],int n,T a) { int l=1, r=n; wh原创 2014-01-16 21:40:10 · 807 阅读 · 1 评论 -
poj 2411 状态压缩dp
横的看成11,竖的看成0/1, 1.相邻2行之间是否冲突就是看a|b是否全是1。 2.同一行是否冲突就是看横着的1的个数是否是奇数。 #include #include #include #include #include using namespace std; long long dp[15][1<<12]; int ok[1<<12]; bool isok(int sta) {原创 2014-01-16 23:34:31 · 853 阅读 · 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 · 865 阅读 · 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 #include using names原创 2013-08-24 16:43:29 · 1762 阅读 · 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 · 2238 阅读 · 0 评论 -
ZOJ 3684 Destroy 树的中心
中心节点就是树的中心,2遍dfs求到树的直径,而中心一定在直径上,顺着直径找到中心就够了。 然后可以一遍树形DP找到最小值或者二分+判断是否访问到叶子节点。 #include #include #include #include using namespace std; struct node { int next; int power; int length原创 2014-05-13 00:02:41 · 990 阅读 · 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 · 830 阅读 · 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 #include using namespace std; int dp[200][70原创 2014-05-05 01:30:35 · 1403 阅读 · 0 评论 -
hdu 3339 In Action 最短路+01背包
题意:n个点m条边的无向图,点和边都有权值。 反复从0点出发,求获得大于点总权值一半的边的边权和。 因为只有100个点,所以直接floyd求最短路,然后一次01背包,DP[i]表示消耗i的油能摧毁的最多的电力。 #include #include #include using namespace std; #define INF 0x3f3f3f3f int n,m,a,b,c; in原创 2014-03-10 20:30:10 · 701 阅读 · 0 评论 -
hdu 2844 多重背包的二进制优化
多重背包解。讲多重背包拆分成完全背包和01背包,01背包部分用二进制优化。 #include #include #include #include #include #include #include #include #include #include #define eps 1e-12 #define INF 0x7fffffff #define maxn 1100 using nam原创 2014-01-12 12:21:56 · 862 阅读 · 0 评论 -
poj 3176 Cow Bowling 数塔dp
从下网上推。 #include #include #include #include #include using 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 · 834 阅读 · 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 #include using namespace std; vector tree[200005]; vector dir[200005]; int dp[200005];原创 2014-01-20 01:14:14 · 1268 阅读 · 0 评论 -
28.uva 10891 Game of Sum 记忆化dp
这题和上次的通化邀请赛的那题一样,而且还是简化版本。。。 那题的题解 请戳这里 dp。。。 #include #include #include #include using namespace std; #define INF 0x3f3f3f3f int dp[105][105]; int a[105]; int sum,n; int pre_sum[105],next_sum原创 2013-08-29 20:49:00 · 823 阅读 · 0 评论 -
hdu 1078 FatMouse and Cheese 记忆化dp
只能横向或竖向走。。。一次横着竖着最多k步。。。不能转弯的。。。。 为毛我的500+ms才跑出来。。。 #include #include #include using 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 · 785 阅读 · 0 评论 -
hdu 4568 Hunter bfs建图+TSP状压DP
TSP问题。原创 2013-08-15 15:29:38 · 1628 阅读 · 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 · 598 阅读 · 0 评论 -
poj 2378 树型dp
和poj1655那道求树的重心基本上一样的,代码也没多大改动。 详情请见 #include #include #include #include using namespace std; #define MAXN 100000 int N; vector node[20005]; int num[MAXN]; //num[i]为以i结点为根的树的所有结点数。 int dp[MAX原创 2013-07-15 08:15:36 · 941 阅读 · 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 #include using namespace std; double sum[9][9原创 2013-07-12 23:49:54 · 603 阅读 · 0 评论 -
poj 1655 Balancing Act(求树的重心)
在一棵树中,去掉一个点,使得剩下的每一颗树的结点数最多的那颗树,结点数最少。 具体解法看注释. /* 定义dp[i]为去掉i结点,剩下的树里,结点最多的那颗树的结点数。 可分为2类情况。 1、由于i结点的儿子结点都成了一棵树的根节点,所以dp[i] = (i的每个儿子所拥有的结点数,的最大值)。 2、而另一种情况就是剩下的那棵树,所以dp[i] = N-原创 2013-07-11 14:39:44 · 1301 阅读 · 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 · 505 阅读 · 0 评论 -
UVA 10590(完全背包,整数拆分+大数加法)
大数加法一位位存效率很低会TLE,我是10亿10亿存的。 #include #include #include #include #include #include using 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 · 1206 阅读 · 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 · 805 阅读 · 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 #include using na原创 2013-07-09 09:05:11 · 709 阅读 · 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 · 514 阅读 · 0 评论 -
hdu 2993 MAX Average Problem 斜率优化DP
详见,算法合集之《浅谈数形结合思想在信息学竞赛中的应用》。 #include #include #include using 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 · 648 阅读 · 0 评论 -
hdu 1300 Pearls DP
方程很好推,n^2过的。 #include #include #include using namespace std; #define maxn 105 int 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 · 727 阅读 · 0 评论 -
poj 3709 K-Anonymous Sequence 斜率优化dp
斜率优化dp原创 2013-07-16 16:58:41 · 859 阅读 · 0 评论 -
hdu 1011 Starship Troopers 树形dp
树形dp dp[i][j]表示 i房间还有j个士兵能获得的最大价值。 当士兵数为0个的时候,就不能继续往下走了。 但当大部队遇到中途的bug为0的房间的时候,就可以不留士兵获取价值。 #include #include #include #include using namespace std; vector tree[105]; int sum[105],val[105]; int dp原创 2013-08-20 09:38:24 · 648 阅读 · 0 评论 -
hdu 4487 概率dp Maximum Random Walk
总共有n轮走法,每次可以向左向右或不动。 求到达最右端的期望 #include #include #include #include using 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 · 884 阅读 · 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 · 674 阅读 · 0 评论