POJ 2486Apple Tree (树形dp)

来源:互联网 发布:叶紫涵网络直播 编辑:程序博客网 时间:2024/05/22 06:35

题意:有一颗苹果树,n个点,n-1条边,每个节点有val[i]个苹果,从根开始走,问最多走k步,能摘得的苹果最大是多少。

分析:树形dp+01背包。

         ① dp[i][j][0]: 对于第i节点,它走j不回来的状态能得到最大苹果。

 ② dp[i][j][1]: 对于第i节点,它走j回来的状态能得到最大苹果。

对于①它可以从u点的其他儿子节点回来后,再走v点不回来,只需多花费1步。

                  dp[u][j][0]=max(dp[u][j][0],dp[u][j-l-1][1]+dp[v][l][0]);
                  
也可在v点回来,在其他儿子节点不回来,需多花费2步
                    dp[u][j][0]=max(dp[u][j][0],dp[u][j-l-2][0]+dp[v][l][1]);

    对于②它只能是每个子树都回来,但需多花费2步。

 dp[u][j][1]=max(dp[u][j][1],dp[u][j-l-2][1]+dp[v][l][1]);

#include <iostream>#include <stdio.h>#include <math.h>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <string>#include <string.h>#include <map>#include <set>using namespace std;#define MAXN 205#define LL long long#define INF 0x3f3fffffstruct node{    int en,next;}E[MAXN*2];int p[MAXN],num,vis[MAXN],n,k,val[MAXN];int dp[105][MAXN][2];int max(int x,int y,int z){    return max(max(x,y),z);}void init(){    memset(p,-1,sizeof(p));    num=0;}void add(int st,int en){    E[num].en=en;    E[num].next=p[st];    p[st]=num++;}void dfs(int u){    vis[u]=1;    int i,j,l;    for(i=p[u];i+1;i=E[i].next)    {        int v=E[i].en;        if(!vis[v])        {            dfs(v);            for(j=k;j>=1;j--)            {                for(l=0;l<=j-2;l++)                {                    if(j-l-2>=0)                    dp[u][j][1]=max(dp[u][j][1],dp[u][j-l-2][1]+dp[v][l][1]);                }                for(l=0;l<=j-1;l++)                {                    if(j-l-1>=0)                    dp[u][j][0]=max(dp[u][j][0],dp[u][j-l-1][1]+dp[v][l][0]);                    if(j-l-2>=0)                    dp[u][j][0]=max(dp[u][j][0],dp[u][j-l-2][0]+dp[v][l][1]);                }            }        }    }    for(i=0;i<=k;i++)    {        dp[u][i][0]+=val[u];        dp[u][i][1]+=val[u];    }}int main(){    int i;    while(scanf("%d%d",&n,&k)!=EOF)    {        init();        for(i=1;i<=n;i++)            scanf("%d",&val[i]);        for(i=1;i<n;i++)        {            int u,v;            scanf("%d%d",&u,&v);            add(u,v);            add(v,u);        }        memset(vis,0,sizeof(vis));        memset(dp,0,sizeof(dp));        dfs(1);        printf("%d\n",max(dp[1][k][0],dp[1][k][1]));    }    return 0;}


0 0
原创粉丝点击