牛客小白月赛躲藏

牛客小白月赛躲藏:

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld


题目描述:

XHRlyb和她的小伙伴Cwbc在玩捉迷藏游戏。
Cwbc藏在多个不区分大小写的字符串中。
好奇的XHRlyb想知道,在每个字符串中Cwbc作为子序列分别出现了多少次。
由于Cwbc可能出现的次数过多,你只需要输出每个答案对2000120420010122取模后的结果。
聪明的你在仔细阅读题目后,一定可以顺利的解决这个问题!


输入描述:

输入数据有多行,每行有一个字符串。

输出描述:

输出数据应有多行,每行表示一个答案取模后的结果。

实例:

示例1

输入
Cwbc
输出
1
说明
Cwbc作为子序列仅出现了1次。

示例2

输入
acdcecfwgwhwibjbkblcmcnco
输出
81
说明
Cwbc作为子序列出现了34=81次。

题解:

很经典的dp 用dp[i][j]来表示前i个字符中 匹配的字符j个数 j这个维度是子序列的长度 这题中j的长度就为4 分别为1,2,3,4.

容易发现,每一个字符的状态都只从它前一个字符的状态转移过来,显然我们可以考虑使用滚动数组来优化空间开销。我们考虑去掉第一维的状态,只保留第二维的状态。那么转移方程就变为:

            dp[1] = (dp[1] + (s[i] ==′ c′)) % Mod 

            dp2] = (dp[2] + (s[i] ==′ w′)∗dp[1]) % Mod 

            dp[3] = (dp[3] + (s[i] ==′ b′)∗dp[2]) % Mod

            dp[4] = (dp[4] + (s[i] ==′ c′)∗dp[3]) % Mod

代码展示[c++ java]:

#include<bits/stdc++.h>
using namespace std ;
typedef long long ll ;
string s ;
ll mod = 2000120420010122 ;
ll dp[10] ;
ll sum ;

//Cwbc

int main(){
	while(cin >> s){
		ll a = 0 , b = 0 , c = 0 , d = 0 ;
		for(int i = s.size() - 1 ; i >= 0 ; i--){
			if(s[i] == 'c' || s[i] == 'C'){
				a = a + 1 ;
				a = a % mod ;
				d = d + c ;
				d = d % mod ;
			}
			if(s[i] == 'w' || s[i] == 'W'){
				c = c + b ;
				c = c % mod ;
			}
			if(s[i] == 'b' || s[i] == 'B'){
				b = a + b ;
				b = b % mod ;
			}
		}
		cout << d % mod << endl ;
	}
	return 0 ;
}
import java.util.Scanner;

public class 躲藏 {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        while(input.hasNext()){
            char[] ch = input.nextLine().toLowerCase().toCharArray();
            long a = 0;
            long b = 0;
            long c = 0;
            long d = 0;
            for(int i=0;i<ch.length;i++) {
                if(ch[i]=='c'){
                    a=(a+1);
                    d = (d+c)% 2000120420010122L;
                }
                else if(ch[i] == 'w')b=(a+b)% 2000120420010122L;
                else if(ch[i] == 'b')c=(c+b)% 2000120420010122L;
            }
            System.out.println(d);
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值