B-Flipping Game
题意:n个灯泡状态只有1、0,操作会使0变1,1变0,每次必须操作k个灯泡(不能重复操作一个灯泡),求m轮操作后有多少种从初始状态到结束状态的方法
思路:动态规划,第一维表示第x轮操作,第二维表示有y个和结束状态相同的灯泡,难点在于状态转移方程的推导
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> PII; const int maxn = 105 + 5; const double eps = 1e-9; int mod = 998244353; ll C[maxn][maxn]; ll dp[maxn][maxn]; int main() { C[1][0] = C[1][1] = 1; for (int i = 0; i < maxn; i++) C[i][0] = 1; for (int i = 1; i < maxn; i++) C[i][i] = 1; for (int i = 2; i < maxn; i++) for (int j = 1; j < i; j++) C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % mod; int t; cin >> t; while (t--) { int n, k, m; cin >> n >> k >> m; memset(dp, 0, sizeof(dp)); string str1, str2; cin >> str1 >> str2; int tmp = 0; for (int i = 0; i < n; i++) tmp += str1[i] == str2[i]; dp[0][tmp] = 1; for (int i = 1; i <= k; i++) for (int j = 0; j <= m; j++) for (int p = 0; p <= n; p++) { if (p - j >= 0 && (n - p) >= (m - j)) dp[i][p - j + m - j] = (dp[i][p - j + m - j] + ((dp[i - 1][p] * C[p][j]) % mod * C[n - p][m - j]) % mod) % mod; } cout << dp[k][n] << endl; } return 0; }