CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)
題目鏈接:點擊查看
題目大意:給出一個 01 字符串,規定求值的過程如下:
現在問,對于所有長度為 n + m 的 01 字符串中,同時滿足下列條件的字符串有多少個
題目分析:網上一堆純組合數學的題解,但是邊界需要判斷的很麻煩,不太喜歡那種解法(也可能是我太菜了,看不明白大佬們的思路),然后發現用 dp 寫會格外簡單
因為涉及到的狀態只有 n 和 m,也就是分別為 0 的剩余個數以及 1 的剩余個數,所以我們設:f[ n ][ m ] 和 g[ n ][ m ] 分別為,剩余 n 個 0 以及 m 個 1 時,最后求值為 1 、0 的方案數
因為滿足第一個條件的字符串就只有 C( n + m , m?) 個,所以不難看出,f[ n ][ m ] + g[ n ][ m ] = C( n + m , m )
然后進行遞推,因為如果想要最后求值為 1,那么前一步一定要是兩個 0 才行,所以不難看出 f[ n ][ m ] = g[ n - 1 ][ m ] = C( n - 1 + m , m ) - f[ n - 1 ][ m ],進一步觀察出 m 在此遞推式中充當常數的角色,所以進一步涉及 dp[ i ] = f[ i ][ m ],這樣轉移方程就推出來了:dp[ i ] = C( m + i - 1 , m ) - dp[ i - 1 ],然后對于 g = 1 和 g = 0 的答案就分別是 dp[ n ] 和 C( n + m , m ) - dp[ n ] 了
剩下一個初始化的問題,dp[ 0 ] 的含義實際上是,剩余 m 個 1 時,最后求值為 1 的方案數,這個需要分類討論一下:
所以此時只需要特判一下 m == 0 的情況了,根據 n 的奇偶輸出答案即可
代碼:
//#pragma GCC optimize(2) //#pragma GCC optimize("Ofast","inline","-ffast-math") //#pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e6+100;const int mod=1e9+7;LL fac[N],inv[N],dp[N];LL q_pow(LL a,LL b) {LL ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod;b>>=1;}return ans; }void init() {fac[0]=1;for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod;inv[N-1]=q_pow(fac[N-1],mod-2);for(int i=N-2;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod; }LL C(int n,int m) {return fac[n]*inv[m]%mod*inv[n-m]%mod; }int main() { #ifndef ONLINE_JUDGE // freopen("data.ans.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);init();int n,m,g;scanf("%d%d%d",&n,&m,&g);if(m==0){if(n%2==0&&g==1||n%2==1&&g==0)puts("1");elseputs("0");return 0;}dp[0]=(m==1?1:0);for(int i=1;i<=n;i++)dp[i]=(C(m+i-1,m)-dp[i-1]+mod)%mod;if(g==1)printf("%lld\n",dp[n]);elseprintf("%lld\n",(C(n+m,m)-dp[n]+mod)%mod);return 0; }?
總結
以上是生活随笔為你收集整理的CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 820D Mi
- 下一篇: CodeForces - 1196F K