NC50505 树形dp

xg

题意

   有一棵二叉苹果树,如果数字有分叉,一定是分两叉,即没有只有一个儿子的节点。这棵树 共N个节点,标号1至N,树根编号一定为1。 

 我们用一根树枝两端连接的节点编号描述一根树枝的位置。一棵有四根树枝的苹果树,因为 树枝太多了,需要剪枝。但是一些树枝上长有苹果,给定需要保留的树枝数量,求最多能留 住多少苹果。

思路

  f[u][j]表示在以u为根的子树保留j个分支可以得到的最大苹果数量  

  nub[u]记录以u为根的数值和。

  f[i][j]的j只需要计算到min(nub【x】,Q)即可。

  f[x][i] = max(f[l][i-1]+e[x][l],f[r][i-1]+e[x][r]);表示当x对于两个根砍掉其中一只的最优解。

  

 

 如果两个都不砍的最优解

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <stack>
#include <set>
#include <vector> 
// #include <bits/stdc++.h>
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define sp ' '
#define endl '\n'
#define FOR(i,a,b) for( int i = a;i <= b;++i)
#define bug cout<<"--------------"<<endl
#define P pair<int, int>
#define fi first
#define se second
#define pb(x) push_back(x)
#define ppb() pop_back()
#define mp(a,b) make_pair(a,b)
#define ms(v,x) memset(v,x,sizeof(v))
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repd(i,a,b) for(int i=a;i>=b;i--)
#define sca3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define sca2(a,b) scanf("%d %d",&(a),&(b))
#define sca(a) scanf("%d",&(a));
#define sca3ll(a,b,c) scanf("%lld %lld %lld",&(a),&(b),&(c))
#define sca2ll(a,b) scanf("%lld %lld",&(a),&(b))
#define scall(a) scanf("%lld",&(a));


using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll powmod(ll a, ll b, ll mod){ll sum = 1;while (b) {if (b & 1) {sum = (sum * a) % mod;b--;}b /= 2;a = a * a % mod;}return sum;}

const double Pi = acos(-1.0);
const double epsilon = Pi/180.0;
const int maxn = 110;
int e[maxn][maxn];
int n,Q;
int f[110][110];
int nub[maxn];
void dfs(int x,int fa)
{
    int l=0,r=0;
    for(int y = 1;y <= n; ++y){
        if(y == fa) continue;
        if(e[x][y] != -1){
            if(l == 0) l = y;
            else r = y;
        }
    }
    if(l == 0&&r==0){
        nub[x] = 1;
        return ;
    }
    dfs(l,x);
    dfs(r,x);
    nub[x] = nub[l]+nub[r]+2;
    rep(i,1,min(nub[x],Q)){
        f[x][i] = max(f[l][i-1]+e[x][l],f[r][i-1]+e[x][r]);
        rep(j,0,i-2){
            f[x][i] = max(f[x][i], f[l][j]+f[r][i-j-2]+e[x][l]+e[x][r]);
        }
    }

}
int main()
{
    //freopen("input.txt", "r", stdin);
    sca2(n,Q);
    memset(e,-1,sizeof(e));
    rep(i,1,n-1){
        int x,y,z;
        sca3(x,y,z);
        e[x][y] = z;
        e[y][x] = z;
    }

    dfs(1,0);

    int ans = 0;

    printf("%d\n",f[1][Q] );

}

 

  

  

posted @ 2020-08-16 14:25  阿斯水生产线  阅读(150)  评论(0编辑  收藏  举报