POJ 1947 (树形DP+背包)
题目链接: http://poj.org/problem?id=1947
题目大意:树中各点都由一条边连接。问要弄出个含有m个点的(子)树,至少需要截去多少条边。
解题思路:
设dp[i][j]为i总根(注意是当前点为总根,不再考虑其父亲,这题是要在原来的树里面切出一个树),留下j个点截去的最少的边。
首先dp[i][1]=子结点数量,即只留下根,要把所有与子节点的边给截掉。
对于dp[i][2~m]:如果取子结点,则dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[t][k]-1)
这里的-1比较巧妙,用的是逆向思维。如果硬要把子树接上去的话,则就被截取边就得少一条,则-1。
至于为什么是dp[i][j-k]+dp[t][k],这里理解成根与儿子共同分一个j,所以取和。
最后的DP的结果比较难想:
ans=min(dp[1][m],dp[2~n][m]+1)
即如果以1为总根,则dp[1][m]就是结果。
否则对于其它点,要使其为总根,则必须切断其与父亲的边,所以结果+1。
#include "cstdio"
#include "iostream"
#include "cstring"
using namespace std;
#define maxn 155
#define inf 0x3f3f3f3f
int n,m,u,v,head[maxn],son[maxn],tol;
int dp[maxn][maxn];
struct Edge
{
int next,to;
}e[maxn];
void addedge(int u,int v)
{
e[tol].to=v;
e[tol].next=head[u];
head[u]=tol++;
}
int dfs(int root)
{
dp[root][]=son[root];
int i=root;
for(int a=head[root];a!=-;a=e[a].next)
{
int t=e[a].to;
dfs(t);
for(int j=m;j>=;j--)
for(int k=;k<=j-;k++)
dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[t][k]-);
}
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
memset(dp,0x3f,sizeof(dp));
memset(head,-,sizeof(head));
for(int i=;i<n;i++)
{
scanf("%d%d",&u,&v);
son[u]++;
addedge(u,v);
}
dfs();
int ans=inf;
for(int i=;i<=n;i++)
{
if(i==) ans=min(ans,dp[i][m]);
else ans=min(dp[i][m]+,ans);
}
printf("%d\n",ans);
}
| 13544792 | neopenx | 1947 | Accepted | 252K | 0MS | C++ | 1010B | 2014-10-19 15:40:17 |
POJ 1947 (树形DP+背包)的更多相关文章
- poj 1947(树形DP+背包)
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10663 Accepted: 4891 ...
- POJ 1155 (树形DP+背包+优化)
题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.但是用户肯定是叶子结点.传到中转站或是用户都要花钱, ...
- poj 1947 树形dp
思路:dp[i][j]表示,以i节点为根,删去j个节点最少要断几条边. 那么dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]);//选取最优状态 dp[u][j]=m ...
- Fire (poj 2152 树形dp)
Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...
- URAL_1018 Binary Apple Tree 树形DP+背包
这个题目给定一棵树,以及树的每个树枝的苹果数量,要求在保留K个树枝的情况下最多能保留多少个苹果 一看就觉得是个树形DP,然后想出 dp[i][j]来表示第i个节点保留j个树枝的最大苹果数,但是在树形过 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- poj 1463(树形dp)
题目链接:http://poj.org/problem?id=1463 思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者. #i ...
- poj 2486( 树形dp)
题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从 ...
- poj 3140(树形dp)
题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include ...
- codeforces 212E IT Restaurants(树形dp+背包思想)
题目链接:http://codeforces.com/problemset/problem/212/E 题目大意:给你一个无向树,现在用两种颜色去给这颗树上的节点染色.用(a,b)表示两种颜色分别染的 ...
随机推荐
- Instance Variables in ruby
Dogs have many shared characteristics, like the abilities to wag their tails and drink water from a ...
- 入侵检测课设之Libnids开发包
Libnids开发包介绍 Libnids是一个用于网络入侵检测开发的专业编程接口,它使用了Libpcap所以它具有捕获数据包的功能.同时,Libnids提供了TCP数据流重组功能,所以对于分析 ...
- 解决android:theme="@android:style/Theme.NoDisplay" 加入这句话后程序不能运行
原因: 原来用的是ActionBarActivity,继承自 ActionBarActivity的类必须指定固定的集中Theme风格,而这些 Theme 风格是需要导入V7中的 appcompat L ...
- 2模02day1题解
源文件在我的网盘上.链接:http://pan.baidu.com/s/1qWPUDRm 密码:k52e (只有机智的人才能看到我的链接) 机智的双重下划线~~~ T1 T1就是一个递推,这题目把我恶 ...
- mysql in 查询优化
2014年11月29日21:01:01 场景:有的时候查询数据库的select in 语句中会有非常多不连续的数值,会很影响查询效率 方法:将select in 查询转换成多个select betwe ...
- 细胞分裂(codevs 2952)
题目描述 Description 著名生物学家F博士发现了一种单细胞生物. 它长得像蚯蚓,分裂速度极快(每分钟一次),分裂也像蚯蚓一样,断成两段,再长成. 它很好斗,只要q只聚集在一起,就会q只一群打 ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通
4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...
- gitlab安装
[root@localhost ~]# wget https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rp ...
- js call apply caller callee bind
call apply bind作用类似.即调用一个对象的一个方法,以另一个对象替换当前对象. call 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) ...
- Telnet命令检测远程主机上的端口是否开启
ping命令不能检测端口,只能检测你和相应IP是否能连通. 本地虚拟机里安装了一个Ubuntu,使用Putty连接22端口操作时提示失败,于是查看对应端口是否开启. Windows下要检测远程主机上的 ...