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

POJ 2486 Apple Tree

2015-09-08 11:59 387 查看
学习树形DP时间不是很长,之前做的都是没有考虑返回这种情况。

现在要考虑一个节点会不会返回,增加一维表示该点是不是返回。

借鉴文章



dp[i][i][0]表示从i出发走j步回到i的可以得到的最大价值

dp[i][i][0]表示从i出发走j步不回到i的可以得到的最大价值

现在有三种措施:要么去s的其他子树呆着,要么去t子树呆着,要么回到s点

1、返回S 那么T就要返回S(dp[t][k][0]),其他子树返回也要返回S点(dp[s][j-k][0])

2、去其他子树 那么T返回到S点(dp[t][k][0]),从S到其他子树不返回(dp[s][j-k][1]);

3、S去T子树不返回 (dp[s][k][1]) 其他子树返回到S点(dp[s][j-k][0] );

1、dp[s][j+2][0]=max(dp[s][j+2][0],dp[s][j-k][0]+dp[t][k][0]);//S-T,T-S(T返回)花两步

2、dp[s][j+2][1]=max(dp[s][j+2][1],dp[s][j-k][1]+dp[t][k][0]);//去其他树 也要从T-S ,S-T,两步

3、dp[s][j+1][1]=max(dp[s][j+1][1],dp[s]j-k][0]+dp[t][k][1]);//去T不返回 只需要走一遍s-t所以加+1

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

const int N=202;
int dp

[2];
int n,m;
int pnt
,nxt
,head
,e=0;
int val
;
void AddEdge(int u,int v)
{
pnt[e]=v;nxt[e]=head[u];head[u]=e++;
}
void dfs(int u,int fa)
{
for(int i=head[u];i!=-1;i=nxt[i])
{
int v=pnt[i];
if(v!=fa){
dfs(v,u);
int s=u,t=v;
for(int j=m;j>=0;j--)
for(int k=0;k<=j;k++)
{
dp[s][j+2][0]=max(dp[s][j+2][0],dp[s][j-k][0]+dp[t][k][0]);
dp[s][j+2][1]=max(dp[s][j+2][1],dp[s][j-k][1]+dp[t][k][0]);
dp[s][j+1][1]=max(dp[s][j+1][1],dp[s][j-k][0]+dp[t][k][1]);
}
}
}
}

int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));
e=0;
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
for(int j=0;j<=m;j++)
dp[i][j][0]=dp[i][j][1]=val[i];
}
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
dfs(1,-1);
printf("%d\n",dp[1][m][1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: