太长时间没做题了,手生了……

ContractedBlock.gif ExpandedBlockStart.gif ZOJ 3506
 1 /*
2 * =====================================================================================
3 *
4 * Filename: dp.cpp
5 *
6 * Description: Problem A on ChengDu
7 *
8 * Version: 1.0
9 * Created: 2011/6/23 21:11:48
10 * Revision: none
11 * Compiler: gcc
12 *
13 * Author: ronaflx
14 * Company: hit-acm-group
15 *
16 * =====================================================================================
17 */
18 #include <cstdio>
19 #include <vector>
20 #include <algorithm>
21 #include <functional>
22 #include <iostream>
23 using namespace std;
24
25 const int N = 1024;
26 const int M = 24;
27 const int INF = 1000000007;
28
29 int n, m, v[N];
30 vector<int> e[N];
31 int dp[N][M];
32 void DP(int now, int father)
33 {
34 dp[now][0] = 0;
35 fill(dp[now] + 1, dp[now] + m + 1, INF);
36 e[now].erase(remove(e[now].begin(), e[now].end(), father), e[now].end());
37 for(vector<int>::iterator iter = e[now].begin();iter != e[now].end();iter++)
38 {
39 DP(*iter, now);
40 for(int i = m;i >= 0;i--)
41 {
42 dp[now][i] += dp[*iter][0];//case 1: 不删除子树,且子树上不删除任何边
43 for(int j = 1;j <= i;j++)//case 2: 不删除子树,且子树删除子树上的边N条
44 dp[now][i] = min(dp[now][i], dp[now][i - j] + dp[*iter][j]);
45 for(int j = 1;j <= e[*iter].size() + 1 && i >= j;j++)//case 3: 删除子树,且删除子树上的N条边
46 dp[now][i] = min(dp[now][i], dp[now][i - j]);
47 }
48 }
49 transform(dp[now], dp[now] + m + 1, dp[now], bind2nd(plus<int>(), v[now]));
50 }
51 int DP()
52 {
53 int ans = INF;
54 DP(0, -1);
55 ans = min(ans, dp[0][m]);
56 if(m == 0) return ans;
57 for(int i = 1;i < n;i++)
58 for(int j = 1;j <= n - e[i].size() - 1 && j <= m;j++)
59 ans = min(ans, dp[i][m - j]);
60 return ans;
61 }
62 int main()
63 {
64 int a, b;
65
66 while (scanf("%d%d", &n, &m) == 2)
67 {
68 for (int i = 0; i < n; ++i)
69 {
70 scanf("%d", &v[i]);
71 e[i].clear();
72 }
73 for (int i = 1; i < n; ++i)
74 {
75 scanf("%d%d", &a, &b);
76 --a, --b;
77 e[a].push_back(b);
78 e[b].push_back(a);
79 }
80 printf("%d ", DP());
81 transform(v, v + n, v, negate<int>());
82 printf("%d\n", -DP());
83 }
84
85 return 0;
86 }

  树形DP,可做题,其实就是在树上的一个背包,但是需要注意的是分3种情况讨论。3种情况都写在注释里了。膜拜一下shi哥的STL,写的太出神入化了!本体代码高仿watashi

期末忙考试……应该不会挂了,加紧练习呀,补回来!

转载于:https://www.cnblogs.com/ronaflx/archive/2011/07/18/2109411.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值