• HDU 7131 Nun Heh Heh Aaaaaaaaaaa


    题面

    题解

    计数DP?

    直接的想法就是统计每个位置左侧 nunhehheh 的个数和右侧 a 的个数。

    但是要避免算重,对串nunhehhehaaa...定位一下,约定在第一个 a 处计数。

    如何统计左侧 nunhehheh 个数?DP,(F[i][k]) 表示 (S[1cdots i]) 包含多少个目标串的 (k) 长前缀

    (F[i][k]=F[i-1][k]+[S[i]==Aim[k]]*F[i-1][k-1])

    代码

    //https://acm.dingbacode.com/showproblem.php?pid=7131
    //2021-10-13 nksbwen
    
    #include <cstdio>
    #include <cstring>
    
    const int MAXL=100111;
    const int MOD=998244353;
    
    int sum(const int &a, const int &b){
    	return a+b-((a+b>=MOD)?MOD:0);
    }
    
    int mul(const int &a, const int &b){
    	return 1LL*a*b%MOD;
    }
    
    int pow(int a, int k){
    	int r=1;
    	while(k){
    		if(k&1)	r=mul(r, a);
    		a=mul(a, a);k>>=1;
    	}
    	return r;
    }
    
    int T;
    char Aim[10]="nunhehheh";
    char input[MAXL];
    int len;
    
    int CntA[MAXL];
    int DP[MAXL][10];
    
    int main(){
    	
    	scanf("%d", &T);
    	
    	while(T--){
    		scanf("%s", input);
    		len=strlen(input);
    		for(int i=0;i<=len;++i)	for(int j=0;j<10;++j)	DP[i][j]=0;
    		DP[0][0]=1;
    		for(int i=0;i<len;++i){
    			for(int j=0;j<=9;++j){
    				DP[i+1][j]=sum(DP[i][j], DP[i+1][j]);
    				if(Aim[j]==input[i]){
    					DP[i+1][j+1]=sum(DP[i][j], DP[i+1][j+1]);
    				}
    			}
    		}
    		CntA[len]=0;
    		for(int i=len;i>0;--i)	CntA[i-1]=CntA[i]+(input[i-1]=='a');
    		int Ans=0;
    		for(int i=0;i<len;++i){
    			if(CntA[i]!=CntA[i+1]){
    				Ans=sum(Ans, mul(DP[i][9], pow(2, CntA[i+1])));
    				// printf("%d %d %d 
    ", i, DP[i][9], CntA[i+1]);
    			}
    		}
    		printf("%d
    ", Ans);
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    Springboot启动前执行方法
    UUID
    vue
    前端进阶
    动态代理
    c# 对接微信公众号JSSDK使用wx.uploadImage 上传图片,后台从微信服务器上下载的图片有问题损坏的解决办法
    浏览器数据库 IndexedDB基础使用
    使用Java命令行编译和打包jar
    ArcGIS JS API 路径回放
    基于Quick_SLPK_Server的NodeJs版I3S服务发布
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/HDU-7131.html
Copyright © 2020-2023  润新知