【*1900 DP+Tree】CF9D

文章介绍了如何使用动态规划解决Codeforces上的Problem-9D问题,这是一个关于二叉树的计数问题。通过设计状态dp[i][j]表示树高为i且结点数小于等于j的方案数,然后从上一层进行转移,计算根节点的两棵子树的组合数。最终通过转移方程求解出答案并减去高度为h-1时的方案数,得到满足条件的树的数量。
摘要由CSDN通过智能技术生成

Problem - 9D - Codeforces

题意:

思路:

计数问题,考虑计数DP

因为它是二叉树,比较特殊,所以可以考虑一下线性DP
按照题目最后要算的答案,状态可以这样设计:

设dp[i][j]表示树高为i,结点数<=j的方案数

它其实就是按照树高为阶段的DP

怎么去转移呢

如果我们按照最后一层,即都是叶子结点的那一层来转移,发现根本不知道怎么算贡献

关于树的DP,一般都是以子树作为主体的

如果我们按照最上面那一层转移,就会发现,转移的过程中,DP的主体就是子树

 这样就很好转移了

dp[i][j]为树高是i,总结点数是j的方案数,主体是整棵树

dp[i-1][j]为树高是i-1(去掉第一层),总结点数是j的方案数,此时这个DP数组的主体就是根节点的两棵子树

这样转移方程就是:

Code:

#include <bits/stdc++.h>

#define int long long

using namespace std;

const int mxn=1e2+10;
 
int N,h;
int dp[mxn][mxn];//树高为i,该树除了子树根节点的子树有j个结点的方案数

void solve(){
    cin>>N>>h;
    for(int i=0;i<=N;i++) dp[i][0]=1ll;
    for(int i=1;i<=N;i++){
        for(int j=1;j<=N;j++){
            for(int k=0;k<j;k++){
                dp[i][j]+=dp[i-1][k]*dp[i-1][j-k-1];
            }
        }
    }
    cout<<dp[N][N]-dp[h-1][N]<<'\n';
}
signed main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int __=1;//cin>>__;
    while(__--)solve();return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值