Solution
树形背包dp大水题,是POJ某道题的弱化版。。。不想说了,据说贪心也能过此题。。
一开始50分,dp数组初始化炸了,表示无语。。
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#define N 111
using namespace std;
int n, v, cur, head_p[N];
int dp[N][N][2];
struct Tadj{int next, obj;} Edg[N<<1];
void Insert(int a, int b){
cur ++;
Edg[cur].next = head_p[a];
Edg[cur].obj = b;
head_p[a] = cur;
}
void dfs(int root, int fa){
for(int i = head_p[root]; ~ i; i = Edg[i].next){
int v = Edg[i].obj;
if(v == fa) continue;
dfs(v, root);
for(int j = n; j >= 1; j--)
for(int k = 1; k <= j; k++){
if(k >= 2){
dp[root][j][0] = max(dp[root][j][0], dp[v][k-2][0] + dp[root][j-k][0]);
dp[root][j][1] = max(dp[root][j][1], dp[v][k-2][0] + dp[root][j-k][1]);
}
dp[root][j][1] = max(dp[root][j][1], dp[v][k-1][1] + dp[root][j-k][0]);
//这里其实还有一个状态不过是废的
//就是让它回到儿子节点但不回到子树的根(明显这不优)
}
}
}
int main(){
scanf("%d%d", &v, &n);
for(int i = 1; i <= v; i++) head_p[i] = -1;
cur = -1;
int a, b;
for(int i = 1; i < v; i++){
scanf("%d%d", &a, &b);
Insert(a+1, b+1);
Insert(b+1, a+1);
}
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= v; i++)
for(int j = 0; j <= n; j++) dp[i][j][0] = dp[i][j][1] = 1;//初始化
dfs(1, 0);
printf("%d\n", max(dp[1][n][0], dp[1][n][1]));
return 0;
}
用力踩,那不堪一击的洁白。