【UNR #6】机器人表演

【UNR #6】机器人表演

by AmanoKumiko

Description

有一个长为n01串,你需要计算t次操作后能得到多少不同的01串。

一次操作的定义为:在串中选两个位置插入一对01使得01前。

998244353取模

Input

第一行两个数n,t

第二行一个长为n01

Output

一行一个整数表示答案

Sample Input

3 1
101

Sample Output

4

Data Constraint

1n300,1t300

Solution

感觉很自然但又很巧妙的一道题

首先有一个朴素的思想

fi,j,k表示填了i个,匹配了j个,插入的01串的和(即把0看做11看做1)为k的方案数

然后匹配每次匹配最前面的

但是这样是假的

比如输入为1001,那么101001这种情况不会被记入

即当k0时,再填1不一定不合法

我们考虑缩减匹配长度,思考缩减到什么样的位置是符合要求的

首先一定会剩下一个0来匹配新的1

然后剩下的字符可以看成是插入了一个合法的括号序中

那么此时新插入的也必须是一个合法括号序

枚举一下每次取最后的满足上面条件的位置就行了

Code

#include<bits/stdc++.h>
using namespace std;
#define F(i,a,b) for(int i=a;i<=b;i++)
#define Fd(i,a,b) for(int i=a;i>=b;i--)
#define mo 998244353
#define N 310

int f[N*3][N][N],n,t,len,to[N],a[N];
char s[N];

int mod(int x){return x>=mo?x-mo:x;}

void upd(int&x,int y){x=mod(x+y);}

bool pd(int l,int r){
	int sum=0;
	F(i,l,r){
		sum+=(a[i]==0?1:-1);
		if(sum<0)return 0;
	}
	return (sum==1);
}

int main(){
	scanf("%d%d",&n,&t);
	scanf("%s",s+1);
	F(i,1,n)a[i]=s[i]-'0';
	len=n+t*2;
	f[0][0][0]=1;
	memset(to,127,sizeof(to));
	F(i,1,n) Fd(j,i-1,0)if(pd(j+1,i)){to[i]=j;break;}
	F(i,0,len-1) F(j,0,n) F(k,0,t)if(f[i][j][k]){
		if(a[j+1]==0&&j+1<=n)upd(f[i+1][j+1][k],f[i][j][k]);
		else upd(f[i+1][j][k+1],f[i][j][k]);
		if(a[j+1]==1&&j+1<=n)upd(f[i+1][j+1][k],f[i][j][k]);
		else{
			if(k-1>=0)upd(f[i+1][j][k-1],f[i][j][k]);
			else if(to[j]<j)upd(f[i+1][to[j]][k],f[i][j][k]);
		}
	}
	printf("%d",f[len][n][0]);
	return 0;
}
posted @   冰雾  阅读(97)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示