题意:从一颗树的根出发走k步最多能摘到的苹果。
思路:树形dp 参考了吴神的博客讲的很清楚了http://www.cnblogs.com/wuyiqi/archive/2012/01/09/2316758.html
1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-04-03 20:09 5 * Filename : poj_2486.cpp 6 * Description : 7 * ************************************************/ 8 9 #include <iostream> 10 #include <cstdio> 11 #include <cstring> 12 #include <cstdlib> 13 #include <cmath> 14 #include <algorithm> 15 #include <queue> 16 #include <stack> 17 #include <vector> 18 #include <set> 19 #include <map> 20 #define MP(a, b) make_pair(a, b) 21 #define PB(a) push_back(a) 22 23 using namespace std; 24 typedef long long ll; 25 typedef pair<int, int> pii; 26 typedef pair<unsigned int,unsigned int> puu; 27 typedef pair<int, double> pid; 28 typedef pair<ll, int> pli; 29 typedef pair<int, ll> pil; 30 31 const int INF = 0x3f3f3f3f; 32 const double eps = 1E-6; 33 const int LEN = 210; 34 int dp[LEN][LEN][2], n, m, vex[LEN]; 35 vector<int> Map[LEN]; 36 37 void dfs(int v, int f){ 38 for(int i=0; i<=m; i++) dp[v][i][0] = dp[v][i][1] = vex[v]; 39 for(int i=0; i<Map[v].size(); i++){ 40 int ch = Map[v][i]; 41 if(ch != f){ 42 dfs(ch, v); 43 for(int j=m; j>=0; j--){ 44 for(int k=0; k<=j; k++){ 45 dp[v][j+2][0] = max(dp[v][j+2][0], dp[ch][j-k][0]+dp[v][k][0]); 46 dp[v][j+2][1] = max(dp[v][j+2][1], dp[ch][j-k][0]+dp[v][k][1]); 47 dp[v][j+1][1] = max(dp[v][j+1][1], dp[ch][j-k][1]+dp[v][k][0]); 48 } 49 } 50 } 51 } 52 } 53 54 int main() 55 { 56 // freopen("in.txt", "r", stdin); 57 58 int a, b; 59 while(cin >> n >> m){ 60 memset(dp, 0, sizeof dp); 61 for(int i=0; i<LEN; i++)Map[i].clear(); 62 for(int i=1; i<=n; i++){ 63 cin >> vex[i]; 64 } 65 for(int i=0; i<n-1; i++){ 66 cin >> a >> b; 67 Map[a].PB(b); 68 Map[b].PB(a); 69 } 70 dfs(1, -1); 71 int ans = 0; 72 for(int i=0; i<=m; i++){ 73 ans = max(ans, dp[1][i][1]); 74 } 75 cout << ans << endl; 76 } 77 return 0; 78 }