[arc059] F - Unhappy Hacking

Problem

你有一个空串,可以进行 n 次操作。
操作分三种:

  1. 在字符串末尾添加字符 0
  2. 在字符串末尾添加字符 1
  3. 删除末尾字符。

问你有多少种操作方案,使得最终得到的字符串为目标串,答案对 109+7 取模。

1n50001|s|n

Input

一个整数 n 和一个字符串 s

Output

一行一个整数,表示方案数。

Sample

Input 1

3
0

Output 1

5

Input 2

300
1100100

Output 2

519054663

Input 3

5000
01000001011101000100001101101111011001000110010101110010000

Output 3

500886057

Solution

考虑dp,定义 fi,j 表示进行 i 次操作,表示出目标串前 j 位的方案数。

如果是第一、二种操作, fi,j 可以由 fi1,j1 转移,但由于 j 可以为 0,因此 j1 可能为负,需特判。

如果是第三种操作,fi,j 可以由 fi1,j+1 转移。由于删去的字符对答案不会造成影响,所以可以为 0,也可为 1。对答案的贡献时两倍的。

因此,fi,j=fi1,j1+2fi1,j+1,边界为 f0,0=1

代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int kmax = 5005;
const int Mod = 1e9 + 7;

int n, m;
string s;
long long f[kmax][kmax];

int main() {
  cin >> n >> s;
  m = s.size();
  f[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    f[i][0] = (f[i - 1][0] + f[i - 1][1] * 2 % Mod) % Mod; // 特殊处理0的情况
    for (int j = 1; j <= i; j++) {
      f[i][j] = (f[i - 1][j - 1] + f[i - 1][j + 1] * 2 % Mod) % Mod;
    }
  }
  cout << f[n][m];
  return 0;
}
posted @   ereoth  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示