由电视台,中转站,和用户的电视组成的体系刚好是一棵树

n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root

现在节点1准备转播一场比赛,已知从一个节点传送数据到达另一个节点,电视台需要一定的费用

若可以传送数据到达用户的节点n-m+1~n,这些用户各自愿意支付一定的费用给电视台

现在电视台希望在不亏本的情况下为尽量多的用户转播比赛

输出最多可以为多少用户转播比赛

背包类型的树形DP第一题

dp[i][j]表示以节点i为根的子树有j个用户获得转播,电视台的最大收益

由于收益有正有负

初始化:

dp[i][0]=0

dp[i][j]=-inf(j>0)

目标:dp[1][j]>=0的条件下最大的j

(dp[1][j]>=0表示电视台不亏本)

dfs的过程递推dp

有个主意的地方写在了注释

 #include<cstdio>
#include<cstring> using namespace std; inline int max(int a,int b)
{
return a>b?a:b;
} const int maxn=;
const int inf=0x3f3f3f3f; int dp[maxn][maxn];
int cost[maxn][maxn];
int siz[maxn];
struct Edge
{
int to,next;
};
Edge edge[maxn];
int head[maxn];
int tot;
int n,m; void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void init()
{
memset(head,-,sizeof head);
tot=;
for(int i=;i<=n;i++)
{
dp[i][]=;
for(int j=;j<=m;j++)
dp[i][j]=-inf;
}
} void solve();
void dfs(int u); int main()
{
while(~scanf("%d",&n))
{
scanf("%d",&m);
init();
for(int i=;i<=n-m;i++)
{
int num;
scanf("%d",&num);
while(num--)
{
int u;
scanf("%d",&u);
scanf("%d",&cost[i][u]);
addedge(i,u);
}
}
for(int i=n-m+;i<=n;i++)
{
scanf("%d",&cost[i][maxn-]);
}
solve();
}
return ;
} void solve()
{
dfs();
for(int j=siz[];j>=;j--)
{
if(dp[][j]>=)
{
printf("%d\n",j);
return ;
}
}
/*
for(int i=0;i<=siz[1];i++)
printf("%d\n",dp[1][i]);
*/
} void dfs(int u)
{
siz[u]=;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(n-m<v)
{
dp[v][]=;
dp[v][]=cost[v][maxn-];
siz[v]=;
}
else
{
dfs(v);
}
siz[u]+=siz[v]; //由于更新dp[u][j]的时候
//dp[u][j-k]需要表示以u为根的子树,有j-k个是从前面的儿子节点取的
//所以这个时候dp[u][j-k]不可以被儿子节点v更新过(保证j-k个都是从前面取的)
//所以递推时j要逆推
//当然,k和j循环的顺序也就不可以交换了
for(int j=siz[u];j>;j--)
{
for(int k=;k<=siz[v];k++)
if(j>=k)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]-cost[u][v]);
}
}
}

POJ 1155 TELE 背包型树形DP 经典题的更多相关文章

  1. hdu 1561 The more, The Better 背包型树形DP 简单题

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  2. 51nod 1353 树 | 树形DP经典题!

    51nod 1353 树 | 树形DP好题! 题面 切断一棵树的任意条边,这棵树会变成一棵森林. 现要求森林中每棵树的节点个数不小于k,求有多少种切法. 数据范围:\(n \le 2000\). 题解 ...

  3. HDU 2196 Computer 树形DP 经典题

    给出一棵树,边有权值,求出离每一个节点最远的点的距离 树形DP,经典题 本来这道题是无根树,可以随意选择root, 但是根据输入数据的方式,选择root=1明显可以方便很多. 我们先把边权转化为点权, ...

  4. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  5. POJ 1155 - TELE 树型DP(泛化背包转移)..

    dp[x][y]代表以x为根的子树..连接了y个终端用户(叶子)..所能获得的最大收益... dp[x][ ]可以看成当根为x时..有个背包空间为0~m...每个空间上记录了到到达这个空间的最大收益. ...

  6. POJ 2486 Apple Tree (树形dp 经典题)

    #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const ...

  7. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

  8. P2016 战略游戏——树形DP大水题

    P2016 战略游戏 树形DP 入门题吧(现在怎么是蓝色标签搞不懂): 注意是看见每一条边而不是每一个点(因为这里错了好几次): #include<cstdio> #include< ...

  9. (树形DP入门题)Anniversary party(没有上司的舞会) HDU - 1520

    题意: 有个公司要举行一场晚会.为了让到会的每个人不受他的直接上司约束而能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会再邀请他的直接的上司,但该人的上司的上司,上司的上司的上司等都可以邀请. ...

随机推荐

  1. HDU 1159 Common Subsequence

    HDU 1159 题目大意:给定两个字符串,求他们的最长公共子序列的长度 解题思路:设字符串 a = "a0,a1,a2,a3...am-1"(长度为m), b = "b ...

  2. HTML5里autofocus属性

    转载:http://www.webhek.com/html5-autofocus/ HTML5给我们带来了一大堆神奇的东西.以前需要用JavaScript和Flash完成的任务,例如表单校验,INPU ...

  3. C#的157个建议--读书笔记(一)

    操作符的重载 ----实现类对象可以像值类型那样进行操作符的操作 实现比较器(IComparable)---实现对象的排序方式 协变:让返回值类型返回比声明的类型派生程度更大的类型:协变支持的两种方式 ...

  4. 【计算机视觉领域】常用的 feature 提取方法,feature 提取工具包

    [计算机视觉领域]常用的 feature 提取方法,feature 提取工具包 利用 VL 工具包进行各种特征的提取: VL 工具包官网地址:http://www.vlfeat.org/index.h ...

  5. CUDA中的流与事件

    流:CUDA流很像CPU的线程,一个CUDA流中的操作按顺序进行,粗粒度管理多个处理单元的并发执行. 通俗的讲,流用于并行运算,比如处理同一副图,你用一个流处理左边半张图片,再用第二个流处理右边半张图 ...

  6. C#中正则表达式的使用

    目前为止,许多编程语言和工具都包含对正则表达式的支持,C#也不例外,C#基础类库中包含有一个命名空间(System.Text.RegularExpressions)和一系列可以充分发挥规则表达式威力的 ...

  7. why does txid_current() assign new transaction-id?

    Naoya: Hi,hackers! I have a question about txid_current(). it is "Why does txid_current() assig ...

  8. mac版photoshop滤镜库报错解法

    http://bbs.pcbeta.com/viewthread-1556878-1-1.html

  9. The launch will only sync the application package on the device!

    在开始学习Android的开发时,有时候可能刚写完一个布局文件,就急忙忙的运行程序,此时会毫不留情的在控制台报错:No Launcher activity found! The launch will ...

  10. linux vi 工具的使用

    linux vi 工具的使用 1.打开文件 vi filename 如果存在该文件,则打开,不存在,则删除 2. 进入vi后,按i建,可以输入内容, 按ESC 在按: ,输入wq保存并退出. 3.移动 ...