POJ1155 TELE(树形DP)

题目是说给一棵树,叶子结点有负权,边有正权,问最多能选多少个叶子结点,使从叶子到根的权值和小于等于0。

考虑数据规模表示出状态:dp[u][k]表示在u结点为根的子树中选择k个叶子结点的最小权值

最后就从d[1][k]中找满足的最大的k。不过单这样转移时间复杂度是指数级,显然这题就是用树上背包了。

不过其实这题时间复杂度不会算= =反正感觉挺靠谱,交了就AC了。。

又做了一道树上背包,HDU1561POJ3345

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 #define INF (1<<29)
 6 #define MAXN 3001
 7 struct Edge{
 8     int u,v,w,next;
 9 }edge[MAXN];
10 int NE,head[MAXN];
11 void addEdge(int u,int v,int w){
12     edge[NE].u=u; edge[NE].v=v; edge[NE].w=w;
13     edge[NE].next=head[u]; head[u]=NE++;
14 }
15
16 int d[MAXN][MAXN],size[MAXN];
17 void dfs(int u){
18     bool isleaf=1;
19     for(int i=head[u]; i!=-1; i=edge[i].next){
20         int v=edge[i].v;
21         dfs(v);
22         size[u]+=size[v];
23         isleaf=0;
24     }
25     if(isleaf) size[u]=1;
26 }
27 int val[MAXN];
28 void dp(int u){
29     bool isleaf=1;
30     for(int i=head[u]; i!=-1; i=edge[i].next){
31         int v=edge[i].v;
32         dp(v);
33         isleaf=0;
34         for(int j=size[u]; j>=1; --j){
35             for(int k=1; k<=min(j,size[v]); ++k) d[u][j]=min(d[u][j],d[u][j-k]+d[v][k]+edge[i].w);
36         }
37     }
38     if(isleaf) d[u][1]=-val[u];
39 }
40 int main(){
41     memset(head,-1,sizeof(head));
42     int n,m,k,a,b;
43     scanf("%d%d",&n,&m);
44     for(int i=1; i<=n; ++i){
45         for(int j=1; j<=m; ++j) d[i][j]=INF;
46     }
47     for(int i=1; i<=n-m; ++i){
48         scanf("%d",&k);
49         while(k--){
50             scanf("%d%d",&a,&b);
51             addEdge(i,a,b);
52         }
53     }
54     for(int i=n-m+1; i<=n; ++i){
55         scanf("%d",val+i);
56     }
57     dfs(1);
58     dp(1);
59     for(int i=m; i>=0; --i){
60         if(d[1][i]<=0){
61             printf("%d",i);
62             break;
63         }
64     }
65     return 0;
66 } 
时间: 2024-10-28 01:18:52

POJ1155 TELE(树形DP)的相关文章

[POJ 1155] TELE (树形dp)

题目链接:http://poj.org/problem?id=1155 题目大意:电视台要广播电视节目,要经过中转机构,到观众.从电视台到中转商到观众是一个树形结构,经过一条边需要支付成本.现在给你每两个节点之间传播的成本,给你每个观众会付的钱,问你电视台在不亏本的情况下最多能给多少个观众看节目. 这是我的第一道树形dp..无耻的看了题解.. 设计状态:dp[u][i]代表以u为根的子树中有i个观众,能够得到的最大收入. 状态转移:dp[u][i] = max(dp[u][i],dp[u][i-

poj1155:树形dp

题意是:给定一棵树,1为根结点表示电视台,有m个叶子节点表示客户,有n-m-1个中间节点表示中转站,每条树边有权值.然后要是跑叶子节点的话边的值只需要++一次就好,叶子节点有权值.问电视台不亏损的情况最多有几个客户可以看到比赛? 转移方程是   dp[v][j] = max(dp[v][j],dp[v][j-i] + dp[k][i] - len),dp[v][1] = Money[v]. 还是挺直观的吧.感觉还是那样,先dfs出子树的所有情况然后再dp求解就好了.

【树形dp】TELE

[POJ1155]TELE Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5376   Accepted: 2973 Description A TV-network plans to broadcast an important football match. Their network of transmitters and users can be represented as a tree. The root o

POJ 1155 TELE 背包型树形DP 经典题

由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送数据到达另一个节点,电视台需要一定的费用 若可以传送数据到达用户的节点n-m+1~n,这些用户各自愿意支付一定的费用给电视台 现在电视台希望在不亏本的情况下为尽量多的用户转播比赛 输出最多可以为多少用户转播比赛 背包类型的树形DP第一题 dp[i][j]表示以节点i为根的子树有j个用户获得转播,电视

poj 1155 TELE(树形泛化背包dp)

/* 这道题还不错,自己想出了思路过得也比较快,也得出了一个小经验,以后写这种题先把关键部分伪代码写出来这样会快很多而且 不那么容易出错,省去很多的调试时间 这道题就是转化为一道树形背包问题.首先把需要付的钱转为负数,对每个叶子结点增加一个子节点表示赚的钱,为正数. 然后记录下当前结点的所有可能的用户数目所花费的钱.所以问题就转化为一道简单的树形dp问题.最后找出盈利为非负数的最大 用户数即可. 有一点要注意dp数组初始化为一个很大的负数,刚开始因为这个问题wa了一遍 用到了num数组存放每个结

POJ 1155 TELE 树形背包问题

题目描述看的莫名其妙,很久才看懂. 就是很裸的树形背包问题吧,状态是dp(i,j)表示节点i取到j个客户能得到的最大收益. 注意一开始初始化的时候所有j为0的时候应该是0,然后其他值都要初始化成负无穷,因为收益有可能是负值. 然后做01背包的时候注意方向,防止出现取某一个元素多次 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set&g

【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock&#39;s blog】

树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AVL树,线段树.SPLAY树,后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点.这里面的关键就是返回的信息部分,这个也没一般性的东西可讲

DP专题&#183;四(树形dp)

1.poj 115 TELE 题意:一个树型网络上有n个结点,1~n-m为信号传送器,n-m+1~n为观众,当信号传送给观众后,观众会付费观看,每铺设一条道路需要一定费用.现在求以1为根,使得收到观众的费用-铺设道路的费用>=0的情况下,能最多给多少个观众观看? 思路:树形dp,dp[i][j]表示以i为根的子树中选择j个观众(叶子)最大的收益. ①如果当前结点为叶子结点,那么其dp[i][0]=0,dp[i][1]=val[i]. ②如果为其他结点,则dp[i][j]=max(dp[i][j]

HDU-2196 Computer (树形DP)

最近在看树形DP,这题应该是树形DP的经典题了,写完以后还是有点感觉的.之后看了discuss可以用树分治来做,以后再试一试. 题目大意 找到带权树上离每个点的最远点.︿( ̄︶ ̄)︿ 题解: 对于每一个点的最远点,就是以这个点为根到所有叶子节点的最长距离.但是如果确定根的话,除了根节点外,只能找到每个节点(度数-1)个子树的最大值,剩下一个子树是该节点当前的父亲节点. 所以当前节点的最远点在当前节点子树的所有叶子节点以及父亲节点的最远点上(当父亲节点的最远点不在当前节点的子树上时), 如果父亲节

UVA-01220 Party at Hali-Bula (树形DP+map)

题目链接:https://vjudge.net/problem/UVA-1220 思路: 树形DP模板题,求最大人数很简单,难点在于如何判断最大人数的名单是否有不同的情况: 解决方法是用一个数组f[manx][2]记录该节点是否出场的情况,为真时代表有多种情况; 具体讨论: 当父节点的值加上某个子节点的值时,他的f的情况也和该子节点一样: 当某个节点dp(i, 0) == dp(i, 1), 则该节点以及它的父节点也一定有多种情况(父节点必定取其中之一). Code: 1 #include<bi