首页 > 其他分享 >[ARC059F] バイナリハック

[ARC059F] バイナリハック

时间:2022-11-24 15:12:33浏览次数:71  
标签:int ll ARC059F ans 字符串 include mod

\(\mathcal Link\)

解决本题的关键在于发现给定字符串没啥用,只需考虑长度

由此考虑有两种做法:

  • 设 \(f_{i,j}\) 表示敲了 \(i\) 次键盘,得到的恰好为字符串中的前 \(j\) 个的方案数。转移的话考虑最后一步是插入还是删除。若为删除,则必为一个长度为 \(j+1\) 且前 \(j\) 位匹配的字符串,方案为 \(2\times f_{i-1,j+1}\),否则为插入,方案为 \(f_{i-1,j-1}\)
  • 考虑到任意一种等长字符串的方案都相同,考虑求出打出任意一个长度为 \(|S|\) 的字符串方案之和并除以 \(2^{|S|}\)

第二种做法的程序:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in,_tp &x){
	x=0;int w=0;char c=getchar();
	for(;!isdigit(c);w|=c=='-',c=getchar());
	for(;isdigit(c);x=x*10+(c^'0'),c=getchar());
	if(w) x=-x;
	return in;
}
#define File(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
const int N=5005,mod=1e9+7;
typedef long long ll;
char s[N];
int dp[N][N];
void add(int &x,int y){
	x+=y;if(x>=mod) x-=mod;
}
ll qpow(ll a,int b){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		b>>=1;a=a*a%mod;
	}
	return ans;
}
int main(){
	int n;io>>n;
	scanf("%s",s+1);
	int len=strlen(s+1);
	dp[0][0]=1;
	for(int i=1;i<=n;++i){
		for(int j=0;j<i;++j){
			if(j==0) add(dp[i][j],dp[i-1][j]);
			else add(dp[i][j-1],dp[i-1][j]);
			add(dp[i][j+1],dp[i-1][j]*2%mod);
		}
	}
	printf("%lld\n",qpow(qpow(2,len),mod-2)*dp[n][len]%mod);
	return 0;
}

标签:int,ll,ARC059F,ans,字符串,include,mod
From: https://www.cnblogs.com/pref-ctrl27/p/16921882.html

相关文章