AT2022 [ARC059D] バイナリハック / Unhappy Hacking
https://www.luogu.com.cn/problem/AT2022
首先可以发现最终答案只和长度有关,和字符串具体是什么没有关系
然后我们考虑DP
设
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示敲了
i
i
i次,匹配了
j
j
j个的方案数
考虑如何转移
- 退格: d p [ i ] [ j ] + = 2 ∗ d p [ i − 1 ] [ j + 1 ] dp[i][j]+=2*dp[i-1][j+1] dp[i][j]+=2∗dp[i−1][j+1] 不用考虑下一位是0/1,因为方案是一样的
- 敲0/1: d p [ i ] [ j ] + = d p [ i − 1 ] [ j − 1 ] dp[i][j]+=dp[i-1][j-1] dp[i][j]+=dp[i−1][j−1]
code:
#include<bits/stdc++.h>
#define N 5005
#define ll long long
#define mod 1000000007
using namespace std;
int n, m;
ll f[N][N];
char st[N];
int main() {
scanf("%d", &n); scanf("%s", st + 1);
m = strlen(st + 1);
f[0][0] = 1;
for(int i = 1; i <= n; i ++)
for(int j = 0; j <= i; j ++)
f[i][j] = (f[i - 1][max(j - 1, 0)] + 2 * f[i - 1][j + 1]) % mod;
printf("%lld", f[n][m]);
return 0;
}