题解:CF2109E Binary String Wowee
考虑一个操作序列
要求
那么显然是从大到小 DP,设
不想思考了,再搞一个 DP 算一下得了。设
时间复杂度
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,r,l) for(int i=(r);i>=(l);i--)
#define repll(i,l,r) for(ll i=(l);i<=(r);i++)
#define perll(i,r,l) for(ll i=(r);i>=(l);i--)
#define pb push_back
#define ins insert
#define clr clear
using namespace std;
namespace ax_by_c{
typedef long long ll;
const ll mod=998244353;
const int N=1005;
int n,k;
char s[N];
ll f[N][N],g0[N][N],g1[N][N];
void slv(){
scanf("%d %d",&n,&k);
scanf("%s",s+1);
rep(i,0,n)rep(j,0,n){
g0[i][j]=0;
if(i==0&&j==0){
g0[i][j]=1;
continue;
}
if(j)g0[i][j]=(g0[i][j]+g0[i][j-1])%mod;
if(i&&(!((i+j-1)&1)))g0[i][j]=(g0[i][j]+g0[i-1][j])%mod;
}
rep(i,0,n)rep(j,0,n){
g1[i][j]=0;
if(i==0&&j==0){
g1[i][j]=1;
continue;
}
if(j)g1[i][j]=(g1[i][j]+g1[i][j-1])%mod;
if(i&&((i+j-1)&1))g1[i][j]=(g1[i][j]+g1[i-1][j])%mod;
}
rep(i,0,n+1)rep(j,0,n+1)f[i][j]=0;
f[n+1][0]=1;
per(i,n+1,2)rep(j,0,k)rep(x,0,k-j){
if(s[i-1]=='0')f[i-1][j+x]=(f[i-1][j+x]+f[i][j]*g0[x][j]%mod)%mod;
else f[i-1][j+x]=(f[i-1][j+x]+f[i][j]*g1[x][j]%mod)%mod;
}
printf("%lld\n",f[1][k]);
}
void main(){
int T=1;
// int csid=0;scanf("%d",&csid);
scanf("%d",&T);
while(T--)slv();
}
}
int main(){
string __name="";
if(__name!=""){
freopen((__name+".in").c_str(),"r",stdin);
freopen((__name+".out").c_str(),"w",stdout);
}
ax_by_c::main();
return 0;
}