• [AGC046C] Shift 题解


    [AGC046C] Shift

    题目大意

    给定一个01串(S)。每次操作可将一个1移到它左边的任意一个0的左边。求进行不多于给定整数(k)此操作所得的不同串个数(对(998244353)取模)。

    数据范围:(1leq |S|leq 300, 0leq kleq 10^9)

    题解

    (n=|S|)。易知至多进行(n)次操作就可以达到所有能达到的状态,于是(kgeq n)时的答案和(k=n)是的答案是一样的,那么就可以把(k)的范围降到(300)了。

    接着考虑用另一种方式表示一个01串:记(cnt_i)为有多少个1的左边恰好有(i)0。容易证明,相同的cnt数组对应相同的01串,不同的cnt数组对应不同的01串。

    然后考虑每一次操作对(cnt)数组的影响:选择两个位置(i,j(i< j)),使(cnt_ileftarrow cnt_i+1, cnt_jleftarrow cnt_j-1)(记此操作为(j ightarrow i))。

    于是就可以愉快地dp了:设(f_{i,j,x})为总变化数为(x)(一次操作产生两次变化),共进行(j)([i+1,n] ightarrow [0,i])的操作所产生的的不同方案数。那么转移方程为:

    [f_{i,j,x}=sum_{0leq yleq x}f_{i-1,j-y,x-y}+sum_{1leq yleq min{n-j,x,cnt_i}}f_{i-1,j+y,x-y} ]

    其中前一部分为进行(y)([i+1,n] ightarrow i)操作所产生的贡献,后一部分为进行(y)(i ightarrow [0,i-1])操作所产生的贡献。

    注意用两个数组储存一下两个求和号,然后直接递推即可。时间复杂度(O(n^3))

    代码(为实现方便,一些数组进行了平移处理):

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define P 998244353
    #define N 305
    
    char s[N];
    int n,k;
    
    int cnt[N];
    
    int dp[N][N][N<<1],s1[N][N<<1],s2[N][N<<1],ans;
    
    int main(){
    	scanf("%s%d",s+1,&k);
    	n=strlen(s+1);
    	k=std::min(k,n)<<1;
    	for(int i=1,tmp=0;i<=n;i++)
    		if(s[i]=='0')
    			tmp++;
    		else
    			cnt[tmp+1]++;
    	dp[0][0][0]=1;
    	for(int j=0;j<=n&&j<=k;j++)
    		s1[j+1][j+1]=1;
    	s2[1][1]=1; 
    	for(int i=1;i<=n+1;i++){
    		for(int j=0;j<=n;j++)
    			for(int x=0;x<=k;x++){
    				dp[i][j][x]=s1[j+1][x+1];
    				int y=std::min(std::min(n-j,x),cnt[i]);
    				if(y)
    					dp[i][j][x]=((dp[i][j][x]+s2[j+2][x])%P+P-s2[j+2+y][x-y])%P;
    			}
    		for(int j=0;j<=n;j++)
    			for(int x=0;x<=k;x++)
    				s1[j+1][x+1]=(s1[j][x]+dp[i][j][x])%P;
    		for(int j=n;j>=0;j--)
    			for(int x=0;x<=k;x++)
    				s2[j+1][x+1]=(s2[j+2][x]+dp[i][j][x])%P;
    	}
    	for(int x=0;x<=k;x++)
    		ans=(ans+dp[n+1][0][x])%P;
    	printf("%d",ans);
    }
    
  • 相关阅读:
    函数的有用信息,装饰器 day12
    函数名、闭包、装饰器 day11
    函数的动态参数与命名空间 day10
    函数 day9
    集合 day8
    文件操作 day8
    基础数据类型补充,及capy daty7
    day7 回顾
    编码补充 daty 6
    字典的增删改查 daty 5
  • 原文地址:https://www.cnblogs.com/Y25t/p/13196935.html
Copyright © 2020-2023  润新知