「JOISC 2020 Day2」遺蹟
阿新 • • 發佈:2020-12-23
https://blog.csdn.net/zxyoi_dreamer/article/details/105273205
https://www.cnblogs.com/Master-Yoda/p/12547799.html
這裡主要說一下如何求\(g\)陣列(\(g_i\)表示有 \(i\) 根石柱,要給它們安排 \(1\cdots i\) 中的初始高度,每種高度數量不超過 \(2\),且它們最終高度是 \(1\cdots i\) 的方案數,不能存在高度為\(0\)的)
大概意思是考慮\(g_{i-j-1}\)
#include<bits/stdc++.h> using namespace std; #define fp(i,l,r) for(register int (i)=(l);(i)<=(r);++(i)) #define fd(i,l,r) for(register int (i)=(l);(i)>=(r);--(i)) #define fe(i,u) for(register int (i)=front[(u)];(i);(i)=e[(i)].next) #define mem(a) memset((a),0,sizeof (a)) #define O(x) cerr<<#x<<':'<<x<<endl #define int long long inline int read(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } void wr(int x){ if(x<0)putchar('-'),x=-x; if(x>=10)wr(x/10); putchar('0'+x%10); } const int MAXN=601,mod=1e9+7,inv2=(mod+1)/2; inline void tmod(int &x){x%=mod;} int n,dp[MAXN],g[MAXN],C[MAXN][MAXN],s0,s1; bool vis[MAXN*2]; main(){ n=read(); fp(i,1,n)vis[read()]=1; fp(i,0,n){ C[i][0]=1; fp(j,1,i)tmod(C[i][j]=C[i-1][j]+C[i-1][j-1]); } g[0]=1; fp(i,1,n)fp(j,0,i-1) tmod(g[i]+=g[j]*g[i-j-1]%mod*C[i-1][j]%mod*(j+2)); dp[0]=1; fd(i,n*2,1){ if(vis[i]){ fd(j,s1,0)if(dp[j])fp(k,0,s1-j) tmod(dp[j+k+1]+=dp[j]*g[k]%mod*C[s1-j][k]%mod*(k+2)); ++s1; } else{ fp(j,0,s1)tmod(dp[j]*=j-s0); ++s0; } } int ans=dp[n]; fp(i,1,n)tmod(ans*=inv2); printf("%lld\n",ans); }