标签:
题意:给定一棵树图,n个节点,有边权,要派k<11个机器人从节点s出发,遍历所有的点,每当1只机器人经过1条边时就会花费该边的边权,边是可重复走的。问遍历完所有点的最小花费?
思路:
非常经典,首先需要知道一点,才能往下推理。就是“如果在t点派c个机器人往孩子u,那么最多只有1个机器人能走会回来到t,否则花费总是不划算的”。
稍微证明一下:
(1)假设派1个机器人往u,逛一圈回到u的父亲t,花费v= 子树u的边权和*2 + e(t,u)*2。若机器人不要了,那花费肯定比v还要少。
(2)假设派2个机器人往u,若要2个机器人都回来,显然花费要比(1)要大。若仅要1个机器人回来,花费仍比“仅派1只机器人往u”要高。(可以试试画一棵有3层的树,头两层只有1个节点,第三层节点数随意即可,来模拟一下就知道结果了)
得到的结论是,要么只派c个机器人去孩子u,且1个都不要走回来(注:0<c<=k);要么派1个机器人出去,且遍历完子树u走回t。
这样已经很好解决了。枚举下点t的孩子数(组),再枚举点t可能获得的机器人数(容量),再枚举给这个孩子派的机器人数(物品)。
还有个初始化DP值的问题,因为每个孩子都是必须遍历的,而常规的分组背包是可选(至多选1件)或者不选物品的,那么可以先将“派1个机器人且回收1个机器人的DP值”丢进背包(保证了此容量下肯定有遍历过子树u),然后若有更好的状态再更新掉此容量。
用DP[t][0]表示“有1个机器人到达t遍历完子树再走回t”的花费。DP[t][i]表示“有i个机器人到达t且遍历完整棵子树t,且不要求回到t”的最小花费。
1 //#include <bits/stdc++.h> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #define pii pair<int,int> 6 #define max(x,y) (x>y?x:y) 7 #define min(x,y) (x<y?x:y) 8 #define INF 0x3f3f3f3f 9 #define LL long long 10 using namespace std; 11 const int N=10050; 12 13 struct node 14 { 15 int from,to,len,next; 16 node(){}; 17 node(int from,int to,int len,int next):from(from),to(to),len(len),next(next){}; 18 }edge[N*2]; 19 20 int head[N],dp[N][12], n, K, edge_cnt; 21 void add_node(int from,int to,int len) 22 { 23 edge[edge_cnt]=node(from,to,len,head[from]); 24 head[from]=edge_cnt++; 25 } 26 27 void DFS(int t,int far) 28 { 29 node e; 30 for(int i=head[t]; i!=-1; i=e.next) //相当于枚举‘组‘ 31 { 32 e=edge[i]; 33 if(e.to^far) 34 { 35 DFS(e.to, t); 36 for(int j=K; j>=0; j-- ) //枚举背包容量 37 { 38 dp[t][j]+=dp[e.to][0]+e.len*2; 39 for(int u=1; u<=j; u++) //枚举买dp[e.to][u]这件商品 40 dp[t][j]=min(dp[t][j], dp[t][j-u]+dp[e.to][u]+u*e.len ); 41 } 42 } 43 } 44 } 45 46 47 48 int main() 49 { 50 freopen("input.txt", "r", stdin); 51 int a,b,c,s; 52 while(~scanf("%d%d%d",&n,&s,&K)) 53 { 54 memset(head, -1, sizeof(head)); 55 memset(dp, 0, sizeof(dp)); 56 edge_cnt=0; 57 for(int i=1; i<n; i++) 58 { 59 scanf("%d%d%d",&a,&b,&c); 60 add_node(a,b,c); 61 add_node(b,a,c); 62 } 63 DFS(s, -1); 64 printf("%d\n", dp[s][K]); 65 } 66 return 0; 67 }
HDU 4003 Find Metal Mineral (树形DP,树形分组背包,经典)
标签:
原文地址:http://www.cnblogs.com/xcw0754/p/4820463.html