POJ 2486 Apple Tree

dp[0][i][j]表示从i点出发,走最多j步返回i点的最优解。

dp[1][i][j]表示从i点出发,走最多j步不返回i点的最优解。

因此有:

dp[0][u][j+2]=max(dp[0][u][j+2],dp[0][v][p]+dp[0][u][j-p]);  //从u点出发,分配p步给子节点v走且返回到v,分配j-p给u点走且回到u,用2步来回u和v。
dp[1][u][j+2]=max(dp[1][u][j+2],dp[0][v][p]+dp[1][u][j-p]);
dp[1][u][j+1]=max(dp[1][u][j+1],dp[1][v][p]+dp[0][u][j-p]);
dp[1][u][j+1]=max(dp[1][u][j+1],dp[0][v][p]+dp[0][u][j-p]);

最终答案为dp[1][1][k]。

//Memory:388K
//Time:79ms
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;

int dp[2][110][210];
int n,k;
int apple[110];

vector<int> G[110];

void init()
{
    memset(dp,0,sizeof dp);
    for(int i=1;i<=n;++i)
        G[i].clear();
}

void DFS(int fa,int u)
{
    int v;
    for(int i=0;i<=k;++i)
        dp[0][u][i]=dp[1][u][i]=apple[u];
    for(int i=0;i<G[u].size();++i) {
        v=G[u][i];
        if(v==fa) continue;
        DFS(u,v);
        for(int j=k;j>=0;--j) {
            for(int p=0;p<=j;++p) {
                dp[0][u][j+2]=max(dp[0][u][j+2],dp[0][v][p]+dp[0][u][j-p]);
                dp[1][u][j+2]=max(dp[1][u][j+2],dp[0][v][p]+dp[1][u][j-p]);
                dp[1][u][j+1]=max(dp[1][u][j+1],dp[1][v][p]+dp[0][u][j-p]);
                dp[1][u][j+1]=max(dp[1][u][j+1],dp[0][v][p]+dp[0][u][j-p]);
            }
        }
    }
}

int main()
{
    int a,b;
    while(scanf("%d%d",&n,&k)==2) {
        for(int i=1;i<=n;++i)
            scanf("%d",apple+i);
        init();
        for(int i=1;i<n;++i) {
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        DFS(-1,1);
        printf("%d\n",dp[1][1][k]);
    }
}

 

posted @ 2013-10-25 21:48  MoriMiya  Views(141)  Comments(0Edit  收藏  举报