http://acm.hdu.edu.cn/showproblem.php?pid=1561
数组开小了越界,查了好久才查出来。。。GCC太能容忍错误了。。。坑!!!
题意:
给你一棵树,选中某一个节点花费1,得到它的价值,而且必须选中父节点才能选中子节点,问:在花费m下,最大价值为多少?
最基本的树形DP,和前面的几道题一样
dp[s][k]表示选中s节点,总花费k时的最大价值
状态转移:
for (int k = m; k >= 2; k--) for (int j = 1; j < k; j++) dp[s][k] = max(dp[s][k], dp[s][k - j] + dp[v][j]);
1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <set> 8 #include <list> 9 #include <map> 10 #include <iterator> 11 #include <cstdlib> 12 #include <vector> 13 #include <queue> 14 #include <stack> 15 #include <algorithm> 16 #include <functional> 17 using namespace std; 18 typedef long long LL; 19 #define ROUND(x) round(x) 20 #define FLOOR(x) floor(x) 21 #define CEIL(x) ceil(x) 22 const int maxn = 210; 23 const int maxm = 410; 24 const int inf = 0x3f3f3f3f; 25 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL; 26 const double INF = 1e30; 27 const double eps = 1e-6; 28 const int P[4] = {0, 0, -1, 1}; 29 const int Q[4] = {1, -1, 0, 0}; 30 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1}; 31 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1}; 32 33 int n, m; 34 int dp[maxn][maxn]; 35 struct Edge 36 { 37 int u, v; 38 int next; 39 } edge[maxm]; 40 int en; 41 int head[maxn]; 42 bool vis[maxn]; 43 int node[maxn]; 44 void addsubedge(int u, int v) 45 { 46 edge[en].u = u; 47 edge[en].v = v; 48 edge[en].next = head[u]; 49 head[u] = en++; 50 } 51 void addedge(int u, int v) 52 { 53 addsubedge(u, v); 54 //addsubedge(v, u); 55 } 56 void init() 57 { 58 memset(head, -1, sizeof(head)); 59 memset(dp, 0, sizeof(dp)); 60 en = 0; 61 memset(node, 0, sizeof(node)); 62 } 63 void input() 64 { 65 int u, w; 66 for (int i = 1; i <= n; i++) 67 { 68 scanf("%d%d", &u, &w); 69 node[i] = w; 70 addedge(u, i); 71 } 72 } 73 void dfs(int s) 74 { 75 //vis[s] = 1; 76 dp[s][1] = node[s]; 77 // cout << "dfs s: " << s << endl; 78 //cout<<"dp[s][1]: "<<s<<" "<<dp[s][1]<<endl; 79 for (int i = head[s]; i != -1; i = edge[i].next) 80 { 81 int v = edge[i].v; 82 //if (!vis[v]) dfs(v); 83 dfs(v); 84 for (int k = m; k >= 2; k--) 85 for (int j = 1; j < k; j++) 86 dp[s][k] = max(dp[s][k], dp[s][k - j] + dp[v][j]); 87 } 88 } 89 void debug() 90 { 91 for (int i = 0; i <= n; i++) cout << head[i] << " "; 92 cout << endl; 93 for (int i = 0; i <= n; i++) 94 { 95 for (int j = 0; j <= m; j++) cout << dp[i][j] << ' '; 96 cout << endl; 97 } 98 } 99 void solve() 100 { 101 node[0] = 0; 102 dfs(0); 103 } 104 void output() 105 { 106 printf("%d ", dp[0][m]); 107 } 108 int main() 109 { 110 // std::ios_base::sync_with_stdio(false); 111 #ifndef ONLINE_JUDGE 112 freopen("in.cpp", "r", stdin); 113 #endif 114 115 while (~scanf("%d%d", &n, &m)) 116 { 117 if (!n && !m) return 0; 118 m++; 119 init(); 120 input(); 121 solve(); 122 // debug(); 123 output(); 124 } 125 return 0; 126 }