日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学)

發布時間:2024/4/11 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 336D Vasily the Bear and Beautiful Strings(dp+组合数学) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:給出一個 01 字符串,規定求值的過程如下:

  • 每次選擇末尾的兩個數字:
  • 如果為 0 0 ,那么替換成一個 1
  • 否則替換成一個 0
  • 循環往復,直至只剩一個數字位置,剩下的數字即為所求
  • 現在問,對于所有長度為 n + m 的 01 字符串中,同時滿足下列條件的字符串有多少個

  • 恰好有 n 個 0 和 m 個 1
  • 求值之后得到的答案等于 g(題目給出)
  • 題目分析:網上一堆純組合數學的題解,但是邊界需要判斷的很麻煩,不太喜歡那種解法(也可能是我太菜了,看不明白大佬們的思路),然后發現用 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 == 1 時,顯然 dp[ 0 ] = 1
  • 當 m > 1 時,因為兩個 1 會替換成一個 0,進而循環形成 1 0 的匹配,最后的求值是 0 ,所以 dp[ 0 ] = 0
  • 所以此時只需要特判一下 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+组合数学)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。