poj 1155(树形dp)

题意:有一个有线电视网络叶子结点是用户,每个用户有一个愿意支付的金额。然后每条边都有话费。问公司在不亏本的情况下最多能满足多少用户。

思路:dp[v][j] = max(dp[v][j], dp[v][j-k]+dp[x][k]-edge(v, x))

其实就是背包问题,但是一开始TLE了一次,这里要有个优化处理一个节点之前需要初始化一下他最多接着几个用户。这样就AC了。

代码如下:

 1 #include <stdio.h>
2 #include <string.h>
3 #include <iostream>
4 #include <algorithm>
5 #include <vector>
6 #include <queue>
7 #include <set>
8 #include <map>
9 #include <string>
10 #include <math.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #define MP(a, b) make_pair(a, b)
14 #define PB(a) push_back(a)
15 using namespace std;
16 const int LEN = 3010;
17 const int INF = 0x3f3f3f3f;
18 typedef pair<int, int> pii;
19 int n, m, dp[LEN][LEN], vex[LEN], num[LEN];
20 vector<pii> Map[LEN];
21
22 void dfs(int v, int fa){
23 if(v > n-m && v <= n) dp[v][1] = vex[v];
24 for(int i=0; i<Map[v].size(); i++){
25 int x = Map[v][i].first;
26 if(x != fa){
27 dfs(x, v);
28 num[v] += num[x];
29 for(int j=num[v]; j>=0; j--){
30 for(int k=0; k<=num[x]; k++){
31 if(j - k >= 0 && dp[x][k] != -INF && dp[v][j-k] != -INF)
32 dp[v][j] = max(dp[v][j], dp[v][j-k]+dp[x][k]-Map[v][i].second);
33 }
34 }
35 }
36 }
37 }
38
39 void init(){
40 for(int i=0; i<LEN; i++)Map[i].clear();
41 memset(num, 0, sizeof num);
42 for(int i=0; i<LEN ;i++){
43 for(int j=0; j<LEN; j++){
44 dp[i][j] = -INF;
45 if(j == 0) dp[i][j] = 0;
46 }
47 }
48 }
49
50 int main()
51 {
52 // freopen("in.txt","r",stdin);
53 //freopen("out.txt","w",stdout);
54
55 int a, b, tn;
56 while(scanf("%d%d", &n, &m)!=EOF){
57 init();
58 for(int i=1; i<=n-m; i++){
59 scanf("%d", &tn);
60 for(int j=0; j<tn; j++){
61 scanf("%d%d", &a, &b);
62 Map[i].PB(MP(a, b));
63 Map[a].PB(MP(i, b));
64 }
65 }
66 for(int i=n-m+1; i<=n ;i++){
67 num[i] = 1;
68 scanf("%d", &vex[i]);
69 }
70 dfs(1, -1);
71 int ans;
72 for(int i=m; i>=0; i--){
73 if(dp[1][i] >= 0){
74 ans = i;
75 break;
76 }
77 }
78 printf("%d\n", ans);
79 }
80 return 0;
81
82 }

时间: 2024-08-06 23:57:50

poj 1155(树形dp)的相关文章

POJ 1155 (树形DP+背包)

题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.如果是中转站则花钱,如果是用户,则收钱.问在不亏本的前提下最多能有多少个用户看到节目. 解题思路: 树形背包.cost=1. 且有个虚根0,取这个虚根也要cost,所以最后的结果是dp[0][m+1]. 本题是cost=1的特殊背包问题,在两个for循环上有一个优化. for(f+1...j....cost) for(1....k...j-cost)

poj 3342(树形dp)

题意:在一个公司中要举办一个聚会,每一个员工有一个奉献值.为了和谐规定直接上下级不能一起出席.让你找出奉献值之和最大为多少. 思路:dp[v][1]表示当前结点选,能获得的最大奉献值,dp[v][0]表示当前节点不选能获得的最大奉献值.状态转移: dp[v][0] = max(dp[v][0], ∑max(dp[x][1], dp[x][0]))x为直接儿子 dp[v][1] = max(dp[v][1], ∑dp[x][0] + vex[v]) 最后答案是max(dp[root][0], dp

poj 1947(树形dp)

题意:一棵树上问你最少切掉几条边使得能分割出一个结点数正好为k的子树. 思路:dp[i][j]表示以i为根切掉j个结点最少要几条边. dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 代码如下: 1 dp[v][j] = min(dp[v][j], dp[v][j-k] + dp[x][k]); 2 } 3 } 4 } 5 } 6 } 7 return vex[v]; 8 } 9 10 int main() 11 { 12 // freopen("

POJ 2486 树形DP

有一颗苹果树,每个节点上面有很多苹果,从一个节点到另外一个可以到达的节点花费1步,求k步最多能吃到多少苹果,起始点为1,可以不回到起始点. 这是典型的回溯型树状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

POJ 3342 树形DP入门题

题目意思和POJ2342一样,只是多加了一个条件,如果最大方案数唯一,输出Yes,不唯一输出No dp的是时候多加一个变量记录答案是否唯一即可 #include "stdio.h" #include "string.h" #include "vector" using namespace std; struct node { int fa; vector<int>child; }data[210]; struct comp { int

POJ 1947 树形DP入门题

给出N个点,N-1个关系,建出树形图,问最少减去几个边能得到节点数为P的树.典型树形DP题 dp[cur][j] :记录cur结点,要得到一棵j个节点的子树去掉的最少边数 转移方程用的背包的思想 对当前树的每一个子树进行计算 砍掉此子树:   dp[cur][j]=dp[cur][j]+1; 不砍掉:           for (l=0;l<=j;l++)  dp[cur][j]=Min(dp[cur][j],dp[cur][l]+dp[next][j-l]); 枚举从该树中留l个节点其他由新

POJ 2342 树形DP入门题

有一个大学的庆典晚会,想邀请一些在大学任职的人来参加,每个人有自己的搞笑值,但是现在遇到一个问题就是如果两个人之间有直接的上下级关系,那么他们中只能有一个来参加,求请来一部分人之后,搞笑值的最大是多少. 树形DP入门题. DP部分: dp[i][0]表示职员i不来参加party,以i为根的子树的最大搞笑值, dp[i][1]表示职员i来参加party,以i为根的子树的最大搞笑值. 转移方程: dp[cur][1]+=dp[next][0]; dp[cur][0]+=Max(dp[next][1]

Fire (poj 2152 树形dp)

Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同时花费为v[i].问最小花费. 以前做过一道类似的题(水库),这道题也差不多.首先来考虑,用\(best[i]\)表示以i为根的子树的最小花费.这样做有什么问题呢?它无法很好的处理消防站重复建的问题. 所以换一种做法.\(best[i]\)依然表示原来的含义,新建一个数组\(f[i][j]\),表示当i这个结

poj 1655 树形dp求取树的重心

http://poj.org/problem?id=1655 Description Consider a tree T with N (1 <= N <= 20,000) nodes numbered 1...N. Deleting any node from the tree yields a forest: a collection of one or more trees. Define the balance of a node to be the size of the large