• [Luogu2015]二叉苹果树(树形dp)


    [Luogu2015] 二叉苹果树

    题目描述

    有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)

    这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。

    我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树

    2   5
      / 
      3   4
        /
        1
    

    现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。

    给定需要保留的树枝数量,求出最多能留住多少苹果。

    输入输出格式

    输入格式:

    第1行2个数,N和Q(1<=Q<= N,1<N<=100)。

    N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。

    每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。

    每根树枝上的苹果不超过30000个。

    输出格式:

    一个数,最多能留住的苹果的数量。

    输入输出样例

    输入样例#1:

    5 2
    1 3 1
    1 4 10
    2 3 20
    3 5 20

    输出样例#1:

    21

    一道树形dp的比较水的题目
    (F[i][j])表示到第(i)个结点,其下保留了(j)个树枝所得的最多的苹果数。
    套路地自下到上转移:

    [F[i][j]=F[son1][x]+F[son2][y]+(v[son1])+(v[son2]) ]

    (x+y=)(j-2)(j-1)(j),讨论一下即可。
    具体看代码。

    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<iostream>
    using namespace std;
    int read()
    {
        int x=0,w=1;char ch=getchar();
        while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*w;
    }
    int n,q,cnt;
    int head[110];
    int dp[110][110];
    int son[110][2];
    int w[110][2];
    struct node{
        int v,to,next;
    }edge[210];
    void add(int x,int y,int z)
    {
        cnt++;
        edge[cnt].to=y;
        edge[cnt].next=head[x];
        edge[cnt].v=z;
        head[x]=cnt;
    }
    void dfs(int,int);
    int main()
    {
        int x,y,z;
        n=read();q=read();
        for(int i=1;i<n;i++)
        {
            x=read();y=read();z=read();
            add(x,y,z);
            add(y,x,z);
        }
        dfs(1,0);
        cout<<dp[1][q];
    }
    void dfs(int k,int f)
    {
        int num=0;
        int v;
        for(int i=head[k];i;i=edge[i].next)
        {
            v=edge[i].to;
            if(v==f) continue;
            son[k][num]=v;
            w[k][num]=edge[i].v;
            num++;
            dfs(v,k);
        }
        if(!num) return;
        for(int i=1;i<=q;i++)
        {
            for(int j=0;j<=i;j++)
            {
                if(j==0)
                    dp[k][i]=max(dp[k][i],dp[son[k][1]][i-1]+w[k][1]);
                else if(j==i)
                    dp[k][i]=max(dp[k][i],dp[son[k][0]][i-1]+w[k][0]);
                else 
                    dp[k][i]=max(dp[k][i],dp[son[k][0]][j-1]+dp[son[k][1]][i-j-1]+w[k][0]+w[k][1]);
            }
        }
    }
    
  • 相关阅读:
    [算法题] 汉诺塔问题
    ubuntu导入torch模块报错
    深度问答之提取语料2
    深度问答之提取语料,导入了yml模块
    python读取文件存到excel中
    zipfile.BadZipFile: File is not a zip file
    查看linux系统时间
    tensorflow:typeerror:‘noneType’ object is not callable
    正则匹配中文标点符号
    re.sub用法
  • 原文地址:https://www.cnblogs.com/lsgjcya/p/9162897.html
Copyright © 2020-2023  润新知