【POJ 2486】 Apple Tree (树形DP)

时间:2023-01-31 21:52:04
Apple Tree

Description

Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each node has an amount of apples. Wshxzt starts her happy trip at one node. She can eat up all the apples in the nodes she reaches. HX is a kind guy. He knows that eating too many can make the lovely girl become fat. So he doesn’t allow Wshxzt to go more than K steps in the tree. It costs one step when she goes from one node to another adjacent node. Wshxzt likes apple very much. So she wants to eat as many as she can. Can you tell how many apples she can eat in at most K steps.

Input

There are several test cases in the input 
Each test case contains three parts. 
The first part is two numbers N K, whose meanings we have talked about just now. We denote the nodes by 1 2 ... N. Since it is a tree, each node can reach any other in only one route. (1<=N<=100, 0<=K<=200) 
The second part contains N integers (All integers are nonnegative and not bigger than 1000). The ith number is the amount of apples in Node i. 
The third part contains N-1 line. There are two numbers A,B in each line, meaning that Node A and Node B are adjacent. 
Input will be ended by the end of file.

Note: Wshxzt starts at Node 1.

Output

For each test case, output the maximal numbers of apples Wshxzt can eat at a line.

Sample Input

2 1
0 11
1 2
3 2
0 1 2
1 2
1 3

Sample Output

11
2
【题意】
  一颗树,n个点(1-n),n-1条边,每个点上有一个权值,求从1出发,走V步,最多能遍历到的权值。 【分析】
  这题做太久了我太傻逼了所以要写博客。
  

  每天都智障24小时。。一开始还看错范围,醉。。
  这题感觉很依赖,于是我首先打dfs序那种的树形依赖,然后发现我不会合并。
  于是我去打子树版本的,搞了超级久,整个一傻逼。
  首先问题是我们是可以往回走,所以设f[i][j][0]表示在点i的子树上走j步不往回走到i的最值,f[i][j][1]表示往回走。
  一个点的子树中不往回走只能有一个,注意不要漏啊不要重啊就好了。
  f[x][j][1]=max(f[x][j][1],f[y][l][1]+f[x][j-l-1][1])
  f[x][j][0]=max(f[x][j][0],f[y][l][0]+f[x][j-l][1])
  f[x][j][0]=max(f[x][j][0],f[y][l][1]+f[x][j-l-1][0])

  有一个地方就是一个子树假设大小是size[x],那么在这棵子树上走的步数不会超过2*size[x],因为每条边最多走两次(走下去走上去),所以可以for到子树大小的2倍,这样可以优化到n^2。

  感觉跟前面的依赖型还是有点不一样,dfs序版的就不能解决,貌似,因为啊回来不回来那个好难搞【POJ 2486】 Apple Tree (树形DP)

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define INF 0xfffffff
#define Maxn 210 struct node
{
int x,y,next;
}t[*Maxn];int len; int n,k;
int first[Maxn],a[Maxn]; int mymax(int x,int y) {return x>y?x:y;} void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} int f[Maxn][Maxn][],ans; void ffind(int x,int fa)
{
f[x][][]=f[x][][]=a[x];
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa)
{
int y=t[i].y;
ffind(y,x);
for(int j=k;j>=;j--)
{
for(int l=;l<=j;l++)
{
f[x][j][]=mymax(f[x][j][],f[y][l][]+f[x][j-l-][]),//l+1
f[x][j][]=mymax(f[x][j][],f[y][l][]+f[x][j-l][]),
f[x][j][]=mymax(f[x][j][],f[y][l][]+f[x][j-l-][]);
// f[x][l+1][0]=mymax(f[x][l+1][0],f[y][l][0]);
}
}
}
} int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
ans=-INF;
k++;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
len=;
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
memset(f,-,sizeof(f));
ffind(,);
for(int i=;i<=k;i++) ans=mymax(ans,mymax(f[][i][],f[][i][]));
printf("%d\n",ans);
}
return ;
}

[POJ 2486]

2016-10-15 11:19:19