hdu1561(树形dp+01背包) The more, The Better

这道题目刚开始想了一阵,因为是树形dp专题,所以没看出来是01背包(重点是要倒序),倒序这个点之前一直没想出来是为什么,因为宝物只有一个,和01背包是一样的意思(其实我现在我没太想明白既然已经是二维了,又为什么要倒序呢),状态转移方程是dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);,因为我在建树的过程中以0为跟,相当于多攻破了一座堡垒,做以求的是dp[0][m+1])
代码如下:

#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int n,m,edge,a;
const int maxn=205;
int dp[maxn][maxn];
int head[maxn],val[maxn];
struct node
{
    int to;
    int next;
}tree[maxn];
void init()
{
    memset(dp,0,sizeof(dp));
    memset(head,-1,sizeof(head));
    edge=0;
}
void addedge(int u,int v)
{
    tree[edge].to=v;
    tree[edge].next=head[u];
    head[u]=edge++;
}
void dfs(int u)
{
    dp[u][1]=val[u];
    for(int i=head[u];i!=-1;i=tree[i].next)
    {
        int v=tree[i].to;
        dfs(v);
        for(int j=n;j>=1;j--)
            for(int k=1;k<j;k++)
            dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
    }
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0)
            break;
        init();
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&a,&val[i]);
            addedge(a,i);
        }
        dfs(0);
        printf("%d\n",dp[0][m+1]);
    }
    return 0;
}

你可能感兴趣的:(dp,树形DP)