HDU4003 树形DP

题意 :给一棵n个节点的树, 节点编号为1~n, 每条边都有一个花费值. 
       有k个机器人从S点出发, 问让机器人遍历所有边,最少花费值多少?

这题最难的地方应该就是如何定义状态了

定义dp[u][i]表示遍历完以u为根的子树的所有边时

使用i个机器人并且这i个机器人都不回到u的最小代价

注意一点 有一种情况,这颗子树上最后没有机器人停留

也就是需要其他子树上面的机器人进去然后再出来,

进去的机器人数目肯定是1个这个是显然的于是用dp[u][0]表示这个状态

所以u->v这条边走了两次 dp[u][i] += dp[v][0] + 2 * w; 

然后枚举用多少机器人是最优的  这里差不多用的是背包的思想

dp[u][i] = min ( dp[u][i], dp[u][i - j] + dp[v][j] + j * w );

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <set>
 7 #include <iostream>
 8 #include <map>
 9 #include <stack>
10 #include <string>
11 #include <vector>
12 #define  pi acos(-1.0)
13 #define  eps 1e-6
14 #define  fi first
15 #define  se second
16 #define  rtl   rt<<1
17 #define  rtr   rt<<1|1
18 #define  bug         printf("******
")
19 #define  mem(a,b)    memset(a,b,sizeof(a))
20 #define  name2str(x) #x
21 #define  fuck(x)     cout<<#x" = "<<x<<endl
22 #define  f(a)        a*a
23 #define  sf(n)       scanf("%d", &n)
24 #define  sff(a,b)    scanf("%d %d", &a, &b)
25 #define  sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
26 #define  sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
27 #define  pf          printf
28 #define  FRE(i,a,b)  for(i = a; i <= b; i++)
29 #define  FREE(i,a,b) for(i = a; i >= b; i--)
30 #define  FRL(i,a,b)  for(i = a; i < b; i++)+
31 #define  FRLL(i,a,b) for(i = a; i > b; i--)
32 #define  FIN         freopen("data.txt","r",stdin)
33 #define  gcd(a,b)    __gcd(a,b)
34 #define  lowbit(x)   x&-x
35 using namespace std;
36 typedef long long  LL;
37 typedef unsigned long long ULL;
38 const int mod = 1e9 + 7;
39 const int maxn = 2e5 + 10;
40 const int INF = 0x3f3f3f3f;
41 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
42 int n, s, k, tot, head[maxn], dp[maxn][15];
43 struct Edge {
44     int v, w, nxt;
45 } edge[maxn];
46 void init() {
47     tot = 0;
48     mem ( head, -1 );
49 }
50 void add ( int u, int v, int w ) {
51     edge[tot].v = v;
52     edge[tot].w = w;
53     edge[tot].nxt = head[u];
54     head[u] = tot++;
55 }
56 void dfs ( int u, int fa ) {
57     for ( int i = head[u]; ~i ; i = edge[i].nxt ) {
58         int v = edge[i].v, w = edge[i].w;
59         if ( v == fa ) continue;
60         dfs ( v, u );
61         for ( int i = k ; i >= 0 ; i-- ) {
62             dp[u][i] += dp[v][0] + 2 * w;
63             for ( int j = 1 ; j <= i ; j++ )
64                 dp[u][i] = min ( dp[u][i], dp[u][i - j] + dp[v][j] + j * w );
65         }
66     }
67 }
68 int main()  {
69     while ( ~sfff ( n, s, k ) ) {
70         init();
71         for ( int i = 1, u, v, w ; i < n ; i++ ) {
72             sfff ( u, v, w );
73             add ( u, v, w ), add ( v, u, w );
74         }
75         mem ( dp, 0 );
76         dfs ( s, -1 );
77         printf ( "%d
", dp[s][k] );
78     }
79     return 0;
80 }
原文地址:https://www.cnblogs.com/qldabiaoge/p/9974243.html