Apple Tree

【题目描述】

一棵苹果树有N(1 <= N <= 100)个节点(编号为1~N),每个节点上都有一定数量的苹果,Mary从根节点(编号为1)开始通过K(0 <= K <= 200)个结点,每通过一个节点,她就可以把此节点上的苹果吃掉,询问Mary最多能够吃掉多少个苹果。

【输入描述】

输入多组数据,每组数据格式如下:

第一行输入两个数N、K;

第二行输入N个数,表示每个节点上的苹果数量;

接下来N-1行,每行输入两个数A、B,表示节点A和节点B相连。

【输出描述】

对于每组数据,输出一个数,表示答案。

【输入样例】

2 1

0 11

1 2

3 2

0 1 2

1 2

1 3

【输出样例】

11

2

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
    int To,Next;
}i[501];
int n,k,Num,f[201][401][2],Head[201],W[201];
void Add(int t1,int t2) //边表。
{
    i[++Num].To=t2;
    i[Num].Next=Head[t1];
    Head[t1]=Num;
}
void DFS(int Root,int Mark)
{
    for (int a=Head[Root];a;a=i[a].Next)
    {
        int T=i[a].To;
        if (T==Mark) //无向边判重。
          continue;
        DFS(T,Root); //DFS回溯。
        for (int b=k;b>=1;b--) //倒序以防重复。
          for (int c=1;c<=b;c++) //断点。
          {
            f[Root][b][0]=max(f[Root][b][0],f[Root][b-c][1]+f[T][c-1][0]); //仔细想想这些常数的含义。
            f[Root][b][0]=max(f[Root][b][0],f[Root][b-c][0]+f[T][c-2][1]);
            f[Root][b][1]=max(f[Root][b][1],f[Root][b-c][1]+f[T][c-2][1]);
          }
    }
}
int main()
{
    while (scanf("%d%d",&n,&k)==2)
    {
        Num=0;
        memset(f,0,sizeof(f));
        memset(Head,0,sizeof(Head)); //初始化。
        for (int a=1;a<=n;a++)
        {
            scanf("%d",&W[a]);
            for (int b=0;b<=k;b++)
              f[a][b][0]=f[a][b][1]=W[a]; //赋初值。
        }
        for (int a=1;a<n;a++)
        {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            Add(t1,t2);
            Add(t2,t1);
        }
        DFS(1,0);
        printf("%d
",max(f[1][k][0],f[1][k][1]));
    }
    return 0;
}

/*
    设f[i][j][0]表示以i为根节点,走j步,不回到i点的能够得到的最大苹果数,f[i][j][1]表示回到i点的。
    则f[i][j][0]可以存在2种转移:
        (1)走i的其他一些子树,然后返回i,再走T子树,不返回;
        (2)走T子树,然后返回i,再走i的其他一些子树,不返回;
    以此类推,f[i][j][1]可以存在1种转移:
        走T子树,然后返回i,再走i的其他一些子树,返回i;
    可得状态转移方程:
        f[i][j][0]=max(f[i][j-k][0]+f[i][k-2][1],f[i][j-k][1]+f[i][k-1][0]);
        f[i][j][1]=max(f[i][j-k][1]+f[i][k-2][1]);
*/
原文地址:https://www.cnblogs.com/Ackermann/p/5977750.html