poj 2486

dp[0][i][j]表示以i为根节点步行j步,且最终回到i,可以得到的最大苹果数量。dp[1][i][j]表示最终不回到i可以得到的最大苹果数量。大笑

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

#define  N 221
#define  inf 0x7f7f7f7f

int dp[2][N][N];
int root;
int n,k;
int cost[111];
vector<int>g[N];
int vis[N];

void dfs(int s){
    for(int i=0;i<=k;i++){
        dp[0][s][i]=dp[1][s][i]=cost[s];//初始化
    }
    vis[s] = 1;
    for(int i=0;i<g[s].size();i++){
        int e = g[s][i];
        if(!vis[e]){
            dfs(e);
            for(int j = k;j >= 0;j--){
                for(int h=0;h <= j;h++){
                    dp[0][s][j+2]=max(dp[0][s][j+2],dp[0][e][h]+dp[0][s][j-h]);
                    dp[1][s][j+2]=max(dp[1][s][j+2],dp[0][e][h]+dp[1][s][j-h]);
                    dp[1][s][j+1]=max(dp[1][s][j+1],dp[1][e][h]+dp[0][s][j-h]);
                }
            }
        }
    }
}


int main(){
    while(scanf("%d%d",&n,&k)!=EOF){
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        memset(cost,0,sizeof(cost));
        for(int i=1;i<=n;i++){
            g[i].clear();
            scanf("%d",&cost[i]);
        }
        for(int i=1;i<n;i++){
            int s,e;
            scanf("%d%d",&s,&e);
            g[s].push_back(e);
            g[e].push_back(s);
        }
        dfs(1);
        printf("%d\n",dp[1][1][k]);
    }
}


你可能感兴趣的:(poj 2486)