您的位置:首页 > 移动开发

ural 1018 Binary Apple Tree

2012-03-11 10:44 316 查看
类型:树形动态规划[经典]

状态:dp(i,j)表示以i为根的子树(还包括i与i的父亲这条边)内,保存j条边最多可以有多少苹果

转移方程:dp(i,j) = max(dp(i.left,k) + dp(i.right,j-1-k)) + i.val (0<=k<=j-1)

思路:输入处理,递归建树,树内dp记忆化搜索实现,输出结果

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

#define MAX 110
int dp[MAX][MAX],apple[MAX][MAX],N,Q;
bool vis[MAX];
struct node{
int left,right;
int val;
}tree[MAX];

void creat(int root) {
vis[root] = true;
for(int i = 1; i <= N; ++i)
if(!vis[i] && apple[root][i] != -1) {
if(tree[root].left != 0)
tree[root].right = i;
else
tree[root].left = i;
tree[i].val = apple[root][i];
creat(i);
}
}

int tree_dp(int i,int j) {
int k;

if(dp[i][j] != -1)
return dp[i][j];
if(j == 0 || i == 0) //!!!
return dp[i][j] = 0;
for(dp[i][j] = 0, k = 0; k != j; ++k){
int ls = tree_dp(tree[i].left, k);
int rs = tree_dp(tree[i].right, j-1-k);
if(dp[i][j] < ls + rs)
dp[i][j] = ls + rs;
}
return dp[i][j] += tree[i].val;
}

int main() {
int a,b,c,i;
cin>>N>>Q;
memset(apple, -1, sizeof(apple));
for(Q++, i = 1; i != N; ++i){
cin>>a>>b>>c;
apple[a][b] = apple[b][a] = c;
}
memset(dp, -1, sizeof(dp));
creat(1);
cout<<tree_dp(1, Q)<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: