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)表示两种颜色分别染的 ...
随机推荐
- Stanford机器学习---第七讲. 机器学习系统设计
原文:http://blog.csdn.net/abcjennifer/article/details/7834256 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...
- web api 解决跨域的问题
web api 总是会遇到跨域的问题,今天我找到了如下方法解决跨域: 1: a:在配置文件中的 加上如下代码 <system.webServer> <httpProtocol> ...
- poj2632 模拟
Crashing Robots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8388 Accepted: 3631 D ...
- tcp/IP点对点通信程序
点对点的通信 服务器端与客户端在建立连接之后创建一个进程 服务器端: 子进程用于接收主机的输入并将数据发送出去.父进程用于接收客户端的数据并输出到主机. 子进程一直等待主机的输入,输入的数据放在发送缓 ...
- 【leetcode】Binary Search Tree Iterator
Binary Search Tree Iterator Implement an iterator over a binary search tree (BST). Your iterator wil ...
- php抽象类的简单应用
抽象类也是面向对象中的重要概念,和接口.继承的概念重要性相当,在面向对象的开发中,所有的对象都是通过类来描述的,但是反过来,并不是所有类都是用来描绘对象的,广义上讲如果一个类中没有足够信息来描述一个具 ...
- canvas API ,通俗的canvas基础知识(四)
今天要讲的内容是canvas的转换功能,前面的内容没用看的同学可以出门右转,先看看前面的基础知识,废话不多说,开始进入正题吧! 何为转换功能?熟悉css3的同学都知道,css3里面有transform ...
- Java for LeetCode 074 Search a 2D Matrix
Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...
- Step deep into GLSL
1 Lighting computation is handled in eye space(需要根据眼睛的位置来计算镜面发射值有多少进入眼睛), hence, when using GLSL (GP ...
- mybatils多次查询问题
@Options(flushCache = true, timeout = 20000)