【UNR #6】机器人表演
2022/8/6 23:22:50
本文主要是介绍【UNR #6】机器人表演,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
【UNR #6】机器人表演
by AmanoKumiko
Description
有一个长为\(n\)的\(01\)串,你需要计算\(t\)次操作后能得到多少不同的\(01\)串。
一次操作的定义为:在串中选两个位置插入一对\(01\)使得\(0\)在\(1\)前。
对\(998244353\)取模
Input
第一行两个数\(n,t\)
第二行一个长为\(n\)的\(01\)串
Output
一行一个整数表示答案
Sample Input
3 1 101
Sample Output
4
Data Constraint
\(1\le n\le 300,1\le t\le 300\)
Solution
感觉很自然但又很巧妙的一道题
首先有一个朴素的思想
设\(f_{i,j,k}\)表示填了\(i\)个,匹配了\(j\)个,插入的\(01\)串的和(即把\(0\)看做\(1\),\(1\)看做\(-1\))为\(k\)的方案数
然后匹配每次匹配最前面的
但是这样是假的
比如输入为\(1001\),那么\(101001\)这种情况不会被记入
即当\(k\)为\(0\)时,再填\(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; }
这篇关于【UNR #6】机器人表演的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-15JavaMailSender是什么,怎么使用?-icode9专业技术文章分享
- 2024-11-15JWT 用户校验学习:从入门到实践
- 2024-11-15Nest学习:新手入门全面指南
- 2024-11-15RestfulAPI学习:新手入门指南
- 2024-11-15Server Component学习:入门教程与实践指南
- 2024-11-15动态路由入门:新手必读指南
- 2024-11-15JWT 用户校验入门:轻松掌握JWT认证基础
- 2024-11-15Nest后端开发入门指南
- 2024-11-15Nest后端开发入门教程
- 2024-11-15RestfulAPI入门:新手快速上手指南