• UOJ#748-[UNR #6]机器人表演【dp】


    正题

    题目链接:https://uoj.ac/problem/748


    题目大意

    有一个长度为 n n n 01 01 01序列,然后 t t t次插入一个 0 0 0和一个 1 1 1,要求 0 0 0 1 1 1前面,求最终能得到多少种本质不同的串。

    1 ≤ n , t ≤ 300 1\leq n,t\leq 300 1n,t300


    解题思路

    我们考虑一个 n + 2 × t n+2\times t n+2×t 01 01 01串是否合法,而且我们最好能搞出一种记录信息最少且唯一的方法。

    我们记录一个 x x x表示当前匹配到的位置,当我们加入一个 0 0 0 1 1 1时,如果恰好能和下一个匹配,我们就匹配。否则如果是 0 0 0,我们再记录一个 y y y表示目前有多少个未匹配的 0 0 0。如果是 1 1 1,如果前面有未匹配的 0 0 0,我们就用未匹配的 0 0 0和这个 1 1 1匹配。

    如果没有我们就一直让匹配位置 x x x往前走,直到出现一个未匹配的 0 0 0,我们可以先预处理出一个 p i p_i pi表示匹配位置 i i i往前跳到出现第一个未匹配 0 0 0的位置。

    这种匹配方法一定是最优的,因为往前跳一到的位置一定是一个 0 0 0,而之后我们拿未匹配的 0 0 0去匹配这个 0 0 0显然不优秀。

    然后我们设 f i , j , k f_{i,j,k} fi,j,k表示现在填到第 i i i个,目前匹配到位置 j j j,前面有 k k k个未匹配的 0 0 0时前面填的方案数转移即可。

    时间复杂度: O ( n 3 ) O(n^3) O(n3)


    code

    #include
    #include
    #include
    using namespace std;
    const int N=305,P=998244353;
    int n,t,f[N*3][N][N],pre[N];
    char s[N];
    void Add(int &x,int y)
    {x=(x+y>=P)?(x+y-P):(x+y);}
    int main()
    {
    //	printf("%d\n",sizeof(f)>>20);
    	scanf("%d%d",&n,&t);
    	scanf("%s",s+1);pre[0]=-1;
    	for(int i=1;i<=n;i++){
    		int p=0;
    		for(int j=i;j>=1;j--){
    			if(s[j]=='1')p++;
    			else p--;
    			if(p==-1){pre[i]=j-1;break;}
    		}
    		if(p!=-1)pre[i]=-1;
    	}
    	f[0][0][0]=1;
    	for(int i=0;i<n+2*t;i++)
    		for(int j=0;j<=n;j++)
    			for(int k=0;k<=t;k++){
    				if(!f[i][j][k])continue;
    				//zero
    				if(s[j+1]=='0')Add(f[i+1][j+1][k],f[i][j][k]);
    				else Add(f[i+1][j][k+1],f[i][j][k]);
    				
    				//one
    				if(s[j+1]=='1')Add(f[i+1][j+1][k],f[i][j][k]);
    				else{
    					if(k)Add(f[i+1][j][k-1],f[i][j][k]);
    					else if(pre[j]!=-1)Add(f[i+1][pre[j]][k],f[i][j][k]);
    				}
    			}
    	printf("%d\n",f[n+2*t][n][0]);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
  • 相关阅读:
    linux安装ffmpeg支持libx264
    国际生态数据获取网络
    idea之maven的安装与配置
    Go 微服务开发框架 DMicro 的设计思路
    辽宁三维企业产品vr场景展示制作
    Python 遍历字典的若干方法
    springboot集成Actuator+Prometheus+Grafana
    23 【事件对象与鼠标事件】
    UVA 294 约数 Divisors
    微服务下的Mybatis xml无效绑定问题分析 Invalid bound statement
  • 原文地址:https://blog.csdn.net/Mr_wuyongcong/article/details/126223642