POJ 2486 apple tree(树形dp)

题意:

一棵树,每个节点有一个权值,求从根节点出发,最多走K步,能够取得的最大权值(可以往回走)。

思路:

dp[1][u][j]  从u节点出发,最多走j步(可以小于j步),并且返回到 u 节点,可以获得的最大权值。

dp[0][u][j] 从u节点出发,最多走j步,最终停留在u的子树节点,可以获得的最大权值。

关键是状态转移方程啊,涉及到停留在 u 点和停留在 v 点展开了优化讨论:

dp[1][u][i+2] = max(dp[1][u][i+2], dp[1][v][i-j] + dp[1][u][j]);
dp[0][u][i+2] = max(dp[0][u][i+2], dp[1][v][i-j] + dp[0][u][j]);
dp[0][u][i+1] = max(dp[0][u][i+1], dp[0][v][i-j] + dp[1][u][j]);

其中v是u节点的孩子节点,j range from K to 0(类似01背包)

代码中使用了一点小小的剪枝:由于没走到一个孩子节点,步数至少减少 1 的,所以可以逐步把步数减 1,最终代码跑到了 32ms.

 
  
#include <iostream>

#include <algorithm>

using namespace std;



const int MAXN = 110;

const int MAXD = 210;



structedge {

    int v;

    edge* next;

} *V[MAXN], ES[MAXN * 2];



int EC, N, K, val[MAXN], dp[2][MAXN][MAXD];

bool vis[MAXN];



void addedge(int u, int v)

{

    ES[++EC].next = V[u];

    V[u] = ES + EC; V[u]->v = v;

}



void initdata(int n)

{

    EC = 0;

    memset(V, 0, sizeof(V));

    memset(vis, false, sizeof(vis));



    for (int i = 1; i <= n; ++i)

        scanf("%d", &val[i]);



    for (int i = 1; i <= n - 1; ++i)

    {

        int a, b;

        scanf("%d %d", &a, &b);

        addedge(a, b);

        addedge(b, a);

    }

}



void treedp(int u, int vol)

{

    vis[u] = true;



    for (int j = 0; j <= vol; ++j)

        dp[0][u][j] = dp[1][u][j] = val[u];



    for (edge* e = V[u]; e; e = e->next)

    {

        int v = e->v;

        if (vis[v])

            continue;



        treedp(v, vol - 1);



        for (int i = vol; i >= 0; --i)

        {

            for (int j = 0; j <= i; ++j)

            {

                dp[1][u][i+2] = max(dp[1][u][i+2], dp[1][v][i-j] + dp[1][u][j]);

                dp[0][u][i+2] = max(dp[0][u][i+2], dp[1][v][i-j] + dp[0][u][j]);

                dp[0][u][i+1] = max(dp[0][u][i+1], dp[0][v][i-j] + dp[1][u][j]);

            }

        }

    }

}



int main()

{

    while (scanf("%d %d", &N, &K) != EOF)

    {

        initdata(N);

        treedp(1, K);

        printf("%d\n", dp[0][1][K]);

    }

    return 0;

}

你可能感兴趣的:(apple)