codeforces 1426F dp题

1426F
2k分的dp哦
给一个带?的字符串,?可以为a,b,c。找有多少个abc子序列(不是找最大的那个子序列)

dp[i]表示到第i个位置的个数
dp[i]记录什么?这里发现a的数量需要存,为读到b或?时构成ab子序列,同理ab,abc
dp[i][0]到第i位a的数量
dp[i][1]。。。ab的数量
dp[i][2]。。。abc的数量
dp[i][0]从dp[i-1][0]转移
关键点,dp过程中遇到?字符,原串个数应当乘以3。
k乘3,k表示3x,x为前面?的数量
比如?a,读到a的时候,该位的个数+3,对该位来说,有aa,ab,ac。4个a,可以自己推

	for(int i=0;i<n;i++) {                         
	 	if(s[i]=='a') {                            
	 	 	dp[i][0]=(dp[i-1][0]+k)%mod;           
	 	 	dp[i][1]=dp[i-1][1];	               
	 	 	dp[i][2]=dp[i-1][2];                   
	 	}                                          
	 	if(s[i]=='b') {                            
	 	 	dp[i][0]=dp[i-1][0];                   
	 	 	dp[i][1]=(dp[i-1][1]+dp[i-1][0])%mod;  
	 	 	dp[i][2]=dp[i-1][2];                   
	 	}                                          
	 	if(s[i]=='c') {                            
	 	 	dp[i][0]=dp[i-1][0];                   
	 	 	dp[i][1]=dp[i-1][1];                   
	 	 	dp[i][2]=(dp[i-1][2]+dp[i-1][1])%mod;  
	 	}                                          
	 	if(s[i]=='?') {                            
	 	 	dp[i][0]=(dp[i-1][0]*3+k)%mod;         
	 	 	dp[i][1]=(dp[i-1][1]*3+dp[i-1][0])%mod;
	 	 	dp[i][2]=(dp[i-1][2]*3+dp[i-1][1])%mod;
	 	 	k*=3;                                  
	 	 	k%=mod;                                
	 	}                                          
	}                                              

最后dp[n][2]为最终值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值