码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 4003 树形dp+分组背包

时间:2015-03-11 10:41:47      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:

依旧是状态分组

——求K个机器人从同一点出发,遍历所有点所需的最小花费

Sample Input
3 1 1
1 2 1
1 3 1
3 1 2
1 2 1
1 3 1
 

 

Sample Output
3
2
 1 /*
 2 HDU 4003
 3 树形DP+只能选一个物品的分组背包
 4 
 5 dp[pos][num]表示以pos为根节点的子树下,用去num个机器人,所得到的最小值
 6 特别的是当num==0的时候,dp[pos][0]表示用一个机器人去走完所有子树,最后又回到pos这个节点
 7 状态转移:dp[pos][num]=min∑{dp[pos_j][num_j]+w_j},pos_j是pos的所有儿子,
 8 
 9 
10 为了让分组背包只选一个,首先让dp[u][0]如背包
11 
12 使用一维数组的“分组背包”伪代码如下:
13 for 所有的组i
14 
15     for v=V..0
16 
17         for 所有的k属于组i
18 
19             f[v]=max{f[v],f[v-c[k]]+w[k]}
20 
21 
22 */
23 
24 #include<stdio.h>
25 #include<algorithm>
26 #include<string.h>
27 #include<iostream>
28 using namespace std;
29 
30 const int MAXN=10010;
31 
32 struct Node
33 {
34     int to;
35     int next;
36     int cost;//该条路径的花费
37 }edge[MAXN*2];//无向树
38 int head[MAXN];
39 int tol;
40 
41 int dp[MAXN][11];//dp[i][j]表示以i为根的树用掉j个人。dp[i][0]表示用了一个人又回到上面的点
42 
43 void init()
44 {
45     memset(head,-1,sizeof(head));
46     tol=0;
47     memset(dp,0,sizeof(dp));
48 }
49 
50 void add(int a,int b,int val)
51 {
52     edge[tol].to=b;
53     edge[tol].cost=val;
54     edge[tol].next=head[a];
55     head[a]=tol++;
56     edge[tol].to=a;
57     edge[tol].cost=val;
58     edge[tol].next=head[b];
59     head[b]=tol++;
60 }
61 
62 int N,K;
63 
64 void dfs(int u,int pre)
65 {
66     for(int i=head[u];i!=-1;i=edge[i].next)
67     {
68         int v=edge[i].to;
69         if(v==pre)continue;
70         dfs(v,u);
71         for(int k=K;k>=0;k--)
72         {
73             dp[u][k]+=dp[v][0]+2*edge[i].cost;//先把dp[u][0]放进背包,保证至少选一个
74          //  分组背包
75             for(int j=1;j<=k;j++)
76               dp[u][k]=min(dp[u][k],dp[u][k-j]+dp[v][j]+j*edge[i].cost);
77         }
78     }
79 }
80 int main()
81 {
82     int S;
83     int a,b,val;
84     while(scanf("%d%d%d",&N,&S,&K)!=EOF)
85     {
86         init();
87         for(int i=1;i<N;i++)
88         {
89             scanf("%d%d%d",&a,&b,&val);
90             add(a,b,val);
91         }
92         dfs(S,-1);
93         printf("%d\n",dp[S][K]);
94     }
95     return 0;
96 }

 

hdu 4003 树形dp+分组背包

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4329133.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!