hdoj4276 (dp + tree packet backpack)

Topic link: https: //vjudge.net/problem/HDU-4276

The meaning of problems: given a tree, starting at 1, the time of V, n end point, each point has a value a [u], each side has a time spent w, n may be seeking to reach the end time V get the greatest value.

Ideas:

  There are two cases to consider edges, which are of a 1-> (go only once), one is not (the need to take two) on the path on the n-path, in order to unify, one may wish to subtracting V -n weight on the path and then the right 1-> n upper path is assigned the value 0.

  At this point it is converted to beg at the start of a return to the starting point in time V maximum value. With dp [u] [j] u expressed in the time point j, and finally back to the maximum value of the point u, dp [u] [j] is initialized to a [u] (0 <= j <= V), the transfer equation as:
    DP [U] [J] = max (DP [U] [J], DP [U] [tmp-J-K] + DP [V] [K].

  U wherein v is the child node, tmp = 2 × w (u, v).

AC Code:

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

int n,V,a[105],e[105][105],dp1[105],dp2[105][505];

void dfs1(int u,int fa){
    dp1[u]=-1;
    if(u==n) dp1[u]=0;
    for(int i=1;i<=n;++i)
        if(e[u][i]!=-1){
            if(i==fa) continue;
            dfs1(i,u);
            if(dp1[i]!=-1){
                dp1[u]=dp1[i]+e[u][i];
                e[u][i]=e[i][u]=0;
            }
        }
}

void dfs2(int u,int fa){
    for(int j=0;j<=V;++j)
        dp2[u][j]=a[u];
    for(int i=1;i<=n;++i)
        if(e[u][i]!=-1){
            if(i==fa) continue;
            dfs2(i,u);
            int tmp=2*e[u][i];
            for(int j=V;j>=tmp;--j)
                for(int k=0;k<=j-tmp;++k)
                    dp2[u][j]=max(dp2[u][j],dp2[u][j-tmp-k]+dp2[i][k]);
        }
}

int main(){
    while(~scanf("%d%d",&n,&V)){
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
                e[i][j]=-1;
        for(int i=1;i<n;++i){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            e[u][v]=e[v][u]=w;
        }
        for(int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        dfs1(1,0);
        if(V<dp1[1]){
            printf("Human beings die in pursuit of wealth, and birds die in pursuit of food!\n");
            continue;
        }
        V-=dp1[1];
        dfs2(1,0);
        printf("%d\n",dp2[1][V]);
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11706809.html