POJ 2486 Apple Tree

来源:互联网 发布:网络贷款受法律保护吗 编辑:程序博客网 时间:2024/05/16 15:45

题目大意:

一棵树上每一个节点都有几个苹果。问在根节点出发,走不大于K步的情况下最多能取多少个苹果。


解题思路:

树形DP,对于每一个子树的根节点src,都有dp[src][i][0],表示从src走i步可以回到src最多能够得到多少苹果。dp[src][i][1]表示从src走i步没有回到src最多能够得到多少苹果。

状态有三种转移方式:
1、用i-j-2步走其他子树回到根节点再用j步走某一子树再回到根节点。

2、用i-j-2步走其他子树回到根节点再用j步走某一子树没有回到根节点。

3、用j步走某一子树再回到根节点在用i-j-1步走其他子树不回到根节点。


注意状态的初始化。


下面是代码:

#include <stdio.h>#include <string.h>#include <algorithm>#include <iostream>#include <math.h>#include <stdlib.h>#include <vector>#include <string>#include <map>#include <queue>using namespace std;int min(int a,int b){    if(a>b)a=b;    return a;}int max(int a,int b){    if(a<b)a=b;    return a;}struct node1{    int to,next;}edge[105*2];int head[105],cnt,n,k,applenum[105],u,v,dp[105][205][2];bool vis[105];void addedge(int u,int v){    edge[cnt].to=v;    edge[cnt].next=head[u];    head[u]=cnt++;    edge[cnt].to=u;    edge[cnt].next=head[v];    head[v]=cnt++;}bool chack(int src){    int t=head[src];    while(t!=-1)    {        if(!vis[edge[t].to])return true;        t=edge[t].next;    }    return false;}void dfs(int src){    if(vis[src])return;    else vis[src]=true;    if(chack(src))    {        int t=head[src];        while(t!=-1)        {            if(vis[edge[t].to])            {                t=edge[t].next;                continue;            }            dfs(edge[t].to);            for(int i=k;i>0;i--)            {                for(int j=0;i-j>=0;j++)                {                    if(i-j-2>=0)                    {                        dp[src][i][0]=max(dp[src][i][0],dp[src][i-j-2][0]+dp[edge[t].to][j][0]);                        dp[src][i][1]=max(dp[src][i][1],dp[src][i-j-2][1]+dp[edge[t].to][j][0]);                    }                    if(i-j-1>=0)                    {                        dp[src][i][1]=max(dp[src][i][1],dp[src][i-j-1][0]+dp[edge[t].to][j][1]);                    }                }            }            t=edge[t].next;        }    }}int main(){    while(scanf("%d%d",&n,&k)!=EOF)    {        cnt=0;        memset(vis,false,sizeof(vis));        memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)        {            head[i]=-1;            scanf("%d",&applenum[i]);        }        for(int i=1;i<=n;i++)        {            for(int j=0;j<=k;j++)            {                dp[i][j][0]=applenum[i];                dp[i][j][1]=applenum[i];            }        }        for(int i=2;i<=n;i++)        {            scanf("%d%d",&u,&v);            addedge(u,v);        }        dfs(1);        printf("%d\n",max(dp[1][k][0],dp[1][k][1]));    }    return 0;}


0 0
原创粉丝点击