poj 2486 Apple Tree (树形dp)

来源:互联网 发布:南昌市网络教研平台 编辑:程序博客网 时间:2024/06/05 10:59

定义dp[u][j][1]表示在以u为根的子树中走了j步并返回了u点所能获得的最大的价值,dp[u][j][0]表示在以u为根的子树中走了j步但没有返回u点所能获得的最大价值。


#include <iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<vector>#define N 105using namespace std;int n,k,weight[N],dp[N][205][2];vector<int>edge[N];void dfs(int u,int fa){        int i,len=edge[u].size(),v,j,l;        dp[u][0][1]=weight[u];        for(i=0;i<len;i++){                v=edge[u][i];                if(v==fa) continue;                dfs(v,u);                for(j=k;j>0;j--){                        for(l=0;j-l-2>=0;l++){                                dp[u][j][1]=max(dp[u][j][1],dp[u][j-l-2][1]+dp[v][l][1]);                                dp[u][j][0]=max( dp[u][j][0]  ,  max( dp[u][j-l-1][1]+dp[v][l][0] , max( dp[u][j-l-2][0] + dp[v][l][1] , dp[u][j-l-1][1] + dp[v][l][1]) ) ) ;                        }                        dp[u][j][0]=max(dp[u][j][0] , max(dp[u][0][1]+dp[v][j-1][0] , dp[u][0][1] + dp[v][j-1][1]) );                }        }}int main(){        while(~scanf("%d%d",&n,&k)){                int i;                memset(dp,-50,sizeof(dp));                for(i=1;i<=n;i++) scanf("%d",weight+i);                for(i=1;i<=n;i++) edge[i].clear();                for(i=1;i<n;i++){                        int a,b;                        scanf("%d%d",&a,&b);                        edge[a].push_back(b);                        edge[b].push_back(a);                }                dfs(1,0);                int ans=0;                for(i=k;i>=0;i--){                        ans=max(ans,max(dp[1][i][0],dp[1][i][1]));                }                cout<<ans<<endl;        }        return 0;}


0 0
原创粉丝点击