摘要:地址:http://poj.org/problem?id=1741题意:给一棵无根树,求任意两点距离小于等于k的点对数量。mark:男人八题。。http://wenku.baidu.com/view/e087065f804d2b160b4ec0b5.html### 上面网址是讲解思路的论文,具体实现没说。我来写写我的实现过程。 首先是要找到重心,那么先递归求出每个点拆掉后能够得到的最大的点的个数,这个点的个数最小的肯定是重心。 然后就按照论文讲解的方法求点对数量,先要求出每个点到重心的距离。代码:#include <cstdio>#include <cstring>#i
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=2196题意:有很多机器通过一棵树连在一起,每条边有一个权值,求每个机器距离最远的路径是多长。mark:这是一个典型的起点不固定的树形dp。我们首先想到的肯定是枚举所有顶点,但是这样计算会有很多重复计算,我们做dp就是为了减少重复计算。 于是我们可以先把它当成一个以任意节点(一般都以编号为1的节点)当根节点做一次dp,dp[i]代表以i为根的子树的最大权值。做完一次后根节点(节点1)肯定已经是最优的了,那么我们现在要想办法更新其他的节点,假如现在要更新节点1的儿子节点son,那么我们首先要计算出除了...
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=1520题意:举办一个party,候选人当中有很多人之间有上下级关系,求没有直接上下级的最多的人数。mark:简单的树形dp题,从每个人的状态着手考虑,每个人要么参加,要么不参加,那么状态dp[i][0]代表参加,dp[i][1]代表不参加。 dp[i][0] += dp[son][1]; dp[i][1] += max(dp[son][1], dp[son][0]);代码:#include <stdio.h>#include <string.h>#include <stdl
阅读全文
摘要:地址:http://poj.org/problem?id=2486题意:有一颗苹果树,每个节点上面有很多苹果,从一个节点到另外一个可以到达的节点花费1步,求k步最多能吃到多少苹果。mark:这是典型的回溯型树状dp。dp[i][j][0]代表以i为根节点的子树最多j步后回到i能吃到的最多的苹果,dp[i][j][1]代表以i为根节点的子树最多j步后不回到i节点最多能吃到的子树。那么状态转移就分三步了。(1)dp[i][j+2][0] = max(dp[i][j+2][0], dp[i][j-k][0]+dp[son][k][0]);(2)dp[i][j+1][1] = max(dp[i][j+
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=4003参见大牛的博客吧http://blog.csdn.net/woshi250hua/article/details/7648099mark:写一点我的总结。 因为该题题目要求的是每个点都必须至少走一次。状态我自己是没想出来,根据大牛的状态。dp[v][0]可以理解为一个机器人跑以v为根节点的分支并回到v点。代码:#include <stdio.h>#include <string.h>#include <stdlib.h>const int N = 10010;s
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=1561题意:要攻克一些城堡,有些城堡可以直接攻克,有些必须要先攻克一个指定城堡才能攻克他。每个城堡里面有一些宝物,求攻克m个城堡的最大宝物数。mark:该题用到一个很实用的技巧就是题目给定的是一片森林,那么我们为这些根节点建立一个共同的根节点,那么就变成一棵树了。 常规树形dp解法。dp[i][j]代表第i个节点为根节点的节点个数为j的最大价值。则dp[v][1] = w[v];(v是叶子节点) dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]);...
阅读全文
摘要:地址:http://poj.org/problem?id=1947题意:给你一棵树,求最少剪掉几条边使能够得到一个p个节点的树。mark:因为节点个数不多,我们可以把节点个数当成一个状态,那么dp[i][j]代表以i为根的子树要变成j个节点需要剪掉的边数。 这里我们考虑状态转移的时候要注意,,我们考虑子节点的时候不用考虑它与父节点的那条边,就当不存在,那么最后求的的最小边数加1就ok了~ 考虑一个节点时,有两种选择,要么剪掉跟子节点相连的边,则dp[i][j] = dp[i][j]+1; 要么不剪掉,则d[i][j] = max(dp[i][j],...
阅读全文
摘要:地址:http://poj.org/problem?id=1155题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号。mark:树状dp。由于求的是最多多少用户,那么我们可以把用户个数当成一个状态。dp[i][j]代表i节点为根节点的子树j个用户的时候最大剩余费用。 则dp[i][j] = max(dp[i][j], dp[i][k]+dp[son][j-k]-w[i][son]); 注意两点,第一点是上面式子中的dp[i][k]必须先用一个tem[MAX]数组提取出来,因为在计算的过程中会相互影响。第二...
阅读全文
摘要:分组背包的学习结束了,收获颇多,分组背包是个很神奇的东西。分组背包经常一般是三种情况。(1)每组物品最多选一个(最常规的)for(i = 0; i < n; i++) //n是总共种类 for(j = vmax; j >= 0; j--) //vmax是背包最大容量 for(k = 0; k < num[i]; k++) //num[]为该类物品个数 if(j >= v[k]) dp[j] = max(dp[j], dp[j-v[k]+w[k]]);这是一维的情况,二维很容易扩展,接下来两种题目必须用二维。而且用到用到01背包里面恰好到达的概念,必须...
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=3535题意:混乱背包,s=0,至少选一种,s=1,最多选一种,s=2,随意选。mark:分别三种情况背包。初始化的时候不能直接把dp[i-1][j]赋值给dp[i][j],必须取最大值。代码:#include <stdio.h>#include <string.h>#include <stdlib.h>const int N = 110;int n,t,m,s;int v[N],w[N];int dp[N][N];int i,f;int max(int a, int
阅读全文
摘要:地址:http://acm.hdu.edu.cn/showproblem.php?pid=3810题意:dota里面敌法师有一个技能blink,就是瞬间移动,而且没有CD。给定很多地方,有些距离比较近的地方是可以相互瞬间移动到的,问能否在达到给定金钱,并求出最小时间。mark:本题把能够相互到达的可以看成一部分,那么就分成很多部分,每个部分没有任何联系,相互做一次01背包,取最小值就好的。 但是问题的关键是本题数据很大,背包容量最大是10亿,时间虽然是30s,但是直接扫肯定是不行的,本来我们是可以用队列的方式解普通的01背包,但是我们用队列跟直接用数组花费空间是一样大的,所以我们需要想办...
阅读全文
摘要:地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834题意:一个有向图,从1出发,到n,初始分数是位置1的分数,每走一步,分数变为之前分数跟当前位置分数的最小公倍数,题目规定每走一步分数必须变化。求多少种方案走到n达到分数k。mark:用bfs做的。正在处于学习STL阶段,写了很长时间。代码:#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <iostream
阅读全文