Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 3856 | Accepted: 2054 |
Description
Input
Output
Sample Input
9 6 3 2 2 3 2 9 3 2 4 2 5 2 3 6 2 7 2 8 2 4 3 3 3 1 1
Sample Output
5
Source
POJ 1155
题目意思:一个电视台的信号发射塔和用户以及传输线路之间构成了一个树状结构,根节点代表发射塔,叶子节点代表用户,树的每一条边都有权值代表传输的代价,问从发射塔发射信号,如何在电视台没有损失的情况下使得最多的用户看到电视节目;
解题思路:树状dp,dp[i][j]表示以i为根节点的子树中能满足j个用户的最大余额:
dp[i][j+k]=max(dp[i][j+k],dp[i][j]+dp[son][k]-cost[i][son]);
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<cstring> 7 using namespace std; 8 const int maxn=3007; 9 const int inf=10000000; 10 struct node 11 { 12 int to,cost; 13 }; 14 vector<node> G[maxn]; 15 int n,m; 16 int dp[maxn][maxn]; 17 int value[maxn],num[maxn]; 18 void init() 19 { 20 for(int i=0;i<maxn;i++) G[i].clear(); 21 memset(dp,0,sizeof(dp)); 22 for(int i=1;i<=n;i++) 23 for(int j=1;j<=m;j++) 24 dp[i][j]=-inf; 25 memset(num,0,sizeof(num)); 26 memset(value,0,sizeof(value)); 27 } 28 void dfs(int point) 29 { 30 for(int i=0;i<G[point].size();i++) 31 { 32 int v=G[point][i].to; 33 dfs(v); 34 for(int j=num[point];j>=0;j--) 35 for(int k=1;k<=num[v];k++) 36 { 37 dp[point][j+k]=max(dp[point][j+k],dp[point][j]+dp[v][k]-G[point][i].cost); 38 } 39 num[point]+=num[v]; 40 } 41 if(point>=n-m+1) num[point]=1; 42 } 43 int main() 44 { 45 //freopen("in.txt","r",stdin); 46 int t,a,b;node n1; 47 while(~scanf("%d%d",&n,&m)){ 48 init(); 49 for(int i=1;i<=n-m;i++) 50 { 51 scanf("%d",&t); 52 for(int j=0;j<t;j++) 53 { 54 scanf("%d%d",&a,&b); 55 n1.to=a;n1.cost=b; 56 G[i].push_back(n1); 57 } 58 } 59 for(int i=n-m+1;i<=n;i++) 60 { 61 scanf("%d",&value[i]); 62 dp[i][1]=value[i]; 63 } 64 dfs(1); 65 int ans=0; 66 for(int i=0;i<=m;i++) 67 { 68 if(dp[1][i]>=0) ans=i; 69 } 70 printf("%d\n",ans); 71 } 72 return 0; 73 }
原文:http://www.cnblogs.com/codeyuan/p/4319487.html