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

POJ 2486 树形背包DP Apple Tree

2015-07-31 14:41 447 查看
设d(u, j, 0)表示在以u为根的子树中至多走k步并且最终返回u,能吃到的最多的苹果。

则有状态转移方程:

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

const int maxn = 100 + 10;
const int maxk = 200 + 10;
int n, k;

int a[maxn];
int d[maxn][maxk][2];
vector<int> G[maxn];

void dfs(int u, int fa)
{
for(int i = 0; i < G[u].size(); i++)
{
int v = G[u][i];
if(v == fa) continue;
dfs(v, u);
for(int j = k; j >= 1; j--)
for(int t = 1; t <= j; t++)
{
if(t > 1) d[u][j][0] = max(d[u][j][0], d[u][j-t][0] + d[v][t-2][0]);
if(t > 1) d[u][j][1] = max(d[u][j][1], d[u][j-t][1] + d[v][t-2][0]);
d[u][j][1] = max(d[u][j][1], d[u][j-t][0] + d[v][t-1][1]);
}
}
}

int main()
{
while(scanf("%d%d", &n, &k) == 2 && n)
{
for(int i = 1; i <= n; i++) G[i].clear();
memset(d, 0, sizeof(d));
for(int i = 1; i <= n; i++)
{
scanf("%d", a + i);
for(int j = 0; j <= k; j++) d[i][j][0] = d[i][j][1] = a[i];
}
for(int i = 1; i < n; i++)
{
int u, v; scanf("%d%d", &u, &v);
G[u].push_back(v); G[v].push_back(u);
}

dfs(1, 0);

printf("%d\n", max(d[1][k][0], d[1][k][1]));
}

return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: