給定 ,對於任意的 ,求出葉子數爲 ,滿足每個葉子到根的路徑上左向邊數量少於 ,每個節點都有 或 個子節點,區分左右的二叉樹數量
一般的DP是 的,所以我們要優化一下狀態
我們考慮像 dfs 遍歷整棵樹,設 表示當前的樹有 個葉子,遍歷到的點左向邊數量爲 的方案數
我們新增一個節點時,葉子數量有可能不變(向左搜索),也有可能增加一個葉子(回溯後向右搜索),葉子數不變時,左向邊數增加了 ,葉子數增加時,左向邊數量減少了 (因爲每個非葉子節點都有 個子節點),所以我們有
那麼最後 就是葉子數爲 時的答案,時間複雜度
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 6000;
const int MOD = 998244353;
int n, m; ll f[N][N];
inline ll add( ll a, ll b ) { return a + b >= MOD ? a + b - MOD : a + b; }
int main()
{
scanf( "%d %d", &m, &n );
f[1][0] = 1;
for( int i = 1; i < n; i ++ )
for( int j = 0; j < m; j ++ )
{
if( j < m - 1 ) f[i][j+1] = add( f[i][j+1], f[i][j] );
if( j > 0 ) f[i+1][j-1] = add( f[i+1][j-1], f[i][j] );
}
for( int i = 1; i <= n; i ++ )
printf( "%lld\n", f[i][0] );
return 0;
}