題目大意:給出一個(gè)長(zhǎng)度為 n 的 01 字符串表示 n 個(gè)燈泡的狀態(tài),1 為點(diǎn)亮,0 為熄滅,現(xiàn)在需要進(jìn)行 k 輪操作,每輪操作可以選擇恰好 m 個(gè)位置,將燈泡的狀態(tài)置反,現(xiàn)在給出初始狀態(tài)和終止?fàn)顟B(tài),問(wèn)有多少種方案可以到達(dá)
題目分析:首先不難看出,如果對(duì)一個(gè)相同的位置操作偶數(shù)次,不會(huì)改變其狀態(tài),只有操作次數(shù)為奇數(shù)時(shí)才會(huì)改變其狀態(tài),那么設(shè)計(jì)二維 dp ,dp[ i ][ j ] 代表的是到達(dá)第 i 輪操作時(shí),共有 j 次操作次數(shù)為奇數(shù)的方案數(shù),轉(zhuǎn)移的話(huà),就是枚舉 k ,代表的是當(dāng)前選擇 k 個(gè)位置從偶數(shù)變?yōu)槠鏀?shù),因?yàn)橐还残枰僮?m 次,所以對(duì)應(yīng)的需要將 m - k 個(gè)位置從奇數(shù)變?yōu)榕紨?shù),因?yàn)槌跏紩r(shí)有 j 次操作為奇數(shù),n - j 次操作為偶數(shù),所以滿(mǎn)足上述 k 的方案數(shù)為 C[ j ][ k ] * C[ n - j ][ m - k ] ,簡(jiǎn)單的組合數(shù)學(xué),然后轉(zhuǎn)移就好了
有點(diǎn)沒(méi)搞清楚的就是初始話(huà),設(shè)初始狀態(tài)和終止?fàn)顟B(tài)共有 num 個(gè)位置不同,則需要給 dp[ 0 ][ num ] 初始為 1 ,答案是 dp[ k ][ 0 ] ,而不能是 dp[ 0 ][ 0 ] = 0 ,然后輸出 dp[ k ][ num ]?
代碼: ?
//#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>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=110;const int mod=998244353;LL C[N][N],dp[N][N];char s1[N],s2[N];void init()//預(yù)處理組合數(shù)
{C[0][0]=1;for(int i=1;i<N;i++){C[i][0]=1;for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;}
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);init();int w;cin>>w;while(w--){memset(dp,0,sizeof(dp));int n,m,k;scanf("%d%d%d",&n,&k,&m);scanf("%s%s",s1,s2);int num=0;for(int i=0;i<n;i++)num+=(s1[i]!=s2[i]);dp[0][num]=1;for(int i=0;i<k;i++)//迭代k次 for(int j=0;j<=n;j++)//有j個(gè)位置操作了奇數(shù)次 for(int k=0;k<=m;k++)//有k個(gè)位置由奇數(shù)次變?yōu)榱伺紨?shù)次 if(j>=k&&n-j>=m-k)dp[i+1][j-k+m-k]=(dp[i+1][j-k+m-k]+dp[i][j]*C[j][k]%mod*C[n-j][m-k])%mod;printf("%lld\n",dp[k][0]);}return 0;
}