HLOJ455 苹果二叉树

题面

题目描述
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)。这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树:
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。 给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,N和Q(1<=Q<= N,1

题解

f [ i ] [ j ] 代表第i个点,保留j个枝条的最大数量。
这里的状态转移要注意,保留的j个枝条要分配到二叉树的两个子树中。
其他就没什么好说了。
还是裸题。

#include<bits/stdc++.h>
using namespace std;
inline int read(){
    int num=0;
    char c=' ';
    bool flag=true;
    for(;c>'9'||c<'0';c=getchar())
    if(c=='-')
    flag=false;
    for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());
    return flag ? num : -num;
}
namespace graph{
    const int maxn=120;
    struct node{
        int y,val;
    };
    vector<node>G[maxn];
    int n,q;
    void insert(int x,int y,int v){
        G[x].push_back((node){y,v});
    }
    void init(){
        n=read();q=read();
        for(int i=1;i<n;i++){
            int x=read();
            int y=read();
            int v=read();
            insert(x,y,v);
            insert(y,x,v);
        }
    }
}using namespace graph;

namespace DP_{
    int f[maxn][maxn];
    int dp(int u,int fa){
        int size=G[u].size();
        int ans=0;
        for(int i=0;i<size;i++){
            int v=G[u][i].y;
            if(v==fa)continue;
            ans+=dp(v,u)+1;
            for(int j=min(ans,q);j>=1;j--){
                for(int k=min(ans,j);k>=1;k--){
                    f[u][j]=max(f[u][j],f[u][j-k]+f[v][k-1]+G[u][i].val);
                }
            }
        }
        return ans;
    }
}using namespace DP_;
int main(){
    init();
    dp(1,0);
    printf("%d\n",f[1][q]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39670434/article/details/80286832
今日推荐