POJ-2486-树形dp

来源:互联网 发布:网络直播营销方案 编辑:程序博客网 时间:2024/05/20 13:04

题目大意:给定一棵n个节点的树,初始位置在1,问走k步最多能获得多少苹果;

题目解析:因为肯定有的路径是返回,有的路径是不返回的,所以这里就需要定义两个dp;dp1[i][j]表示在第i个节点有j步最后返回i,dp2不返回;

状态转移方程如下:

dp1[root][j]=max(dp1[root][j],dp1[root][j-k-2]+dp1[v][k]);在v中返回;
dp2[root][j]=max(dp2[root][j],dp2[root][j-k-2]+dp1[v][k]);v中不返回,在其余的某个返回;dp2[root][j]=max(dp2[root][j],dp1[root][j-k-1]+dp2[v][k]);v中返回,某个其余的不返回;

AC代码:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<string>using namespace std;const int inf=0x3fffffff;const int maxn=110;int tot,head[maxn],n,m,dp[maxn][210],dp1[maxn][210],dp2[maxn][210];bool vis[maxn];struct Edge{        int to,next;}edge[maxn<<1];void init(){        memset(head,-1,sizeof(head));        tot=0;}void addedge(int u,int v){        edge[tot].to=v;        edge[tot].next=head[u];        head[u]=tot++;}void dfs(int root,int fa){        for(int i=head[root];i!=-1;i=edge[i].next)        {                int v=edge[i].to;                if(v==fa)       continue;                dfs(v,root);                for(int j=m;j>=0;j--)                {                       for(int k=0;k<=j;k++)                       {                               if(j>=k+2)                               {                                         dp1[root][j]=max(dp1[root][j],dp1[root][j-k-2]+dp1[v][k]);                                         dp2[root][j]=max(dp2[root][j],dp2[root][j-k-2]+dp1[v][k]);                               }                               if(j>=k+1)                               {                                       dp2[root][j]=max(dp2[root][j],dp1[root][j-k-1]+dp2[v][k]);                               }                       }                }        }}int main(){        while(scanf("%d%d",&n,&m)!=EOF)        {                init();                memset(dp,0,sizeof(dp));                memset(dp1,0,sizeof(dp1));                memset(dp2,0,sizeof(dp2));                for(int i=1;i<=n;i++)                {                        scanf("%d",&dp1[i][0]);                        dp2[i][0]=dp1[i][0];                }                for(int i=1;i<n;i++)                {                        int u,v;                        scanf("%d%d",&u,&v);                        addedge(u,v);                        addedge(v,u);                }                dfs(1,-1);                int max1=0;                for(int i = 0 ; i <= m ; i++) {                        max1 = max(max1,dp2[1][i]) ;                }                printf("%d\n",max1);        }        return 0;}


0 0
原创粉丝点击