【BZOJ4824】 [Cqoi2017]老C的键盘

xiaoxiao2021-02-28  86

树形dp!

dp[x][i]表示dp到x且x的排名为i的方案数,然后组合什么的乘一乘就好了。具体转移我也没想过,直接看std了。。(应该挺简单的吧)

#include <bits/stdc++.h> #define N 109 #define ll long long #define mod 1000000007 #define gc getchar() using namespace std; ll n,a[N],dp[N][N],sum[N][N],size[N],c[N][N],tmp[N]; void dfs(ll x) { dp[x][1]=sum[x][1]=size[x]=1; for (ll son=x<<1;son<=(x<<1|1);son++) { if (son>n) return; dfs(son); for (ll i=1;i<=size[x]+size[son];i++) tmp[i]=0; for (ll i=1;i<=size[x];i++) for (ll j=0;j<=size[son];j++) if (a[son]==2) tmp[i+j]+=dp[x][i]*sum[son][j]%mod*c[i-1+j][i-1]%mod*c[size[x]-i+size[son]-j][size[x]-i]%mod; else tmp[i+j]+=dp[x][i]*(sum[son][size[son]]-sum[son][j]+mod)%mod*c[i-1+j][i-1]%mod*c[size[x]-i+size[son]-j][size[x]-i]%mod; for (ll i=1;i<=size[x]+size[son];i++) dp[x][i]=tmp[i]%mod,sum[x][i]=(sum[x][i-1]+dp[x][i])%mod; size[x]+=size[son]; } } int main() { scanf("%lld",&n); for (ll i=0;i<=n;i++) for (ll j=0;j<=n;j++) if (j==0||j==i) c[i][j]=1; else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; for (ll i=2;i<=n;i++) { char ch; while (ch=gc,ch!='<'&&ch!='>'); if (ch=='<') a[i]=1; else a[i]=2; } dfs(1); printf("%lld\n",sum[1][n]); return 0; }

转载请注明原文地址: https://www.6miu.com/read-73890.html

最新回复(0)