H. Happy Morse Code

题目链接:https://codeforces.com/gym/102875/problem/H

题意:

用暴力搜索+剪枝T了,长记性了以后

给定一个长度为n的01串str,以及m个由不同字母代表的长度小于等于5的01串。

求str有多少种表示方法

思路:

线性dp

由于答案需要取模,所以可能导致方案数变为0从而影响递推结果

因此将可行性和方案数分开dp

对于方案数记f[i]:遍历到位置i的总方案数

f[i]需要从f[i-1]转移过来,但是当i=0时不需要

总方案数为f[n-1],过程取模

可解性过程类似,当dp数组大于1时直接记为2即可

vector<string>a;
string str;
int n,m;
int f[maxn];
int dp[maxn];
void solve(){
    cin>>n>>m;
    a.clear();
    memset(f,0,sizeof f);
    memset(dp,0,sizeof dp);
    rep(i,1,m){
        char ch;cin>>ch;
        string s;cin>>s;
        a.pb(s);
    }
    cin>>str;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            int len=a[j].size();
            if(i+len-1>=n)continue;
            if(str.substr(i,len)==a[j]){
                if(i&&f[i-1]){
                    f[i+len-1]+=f[i-1];
                    f[i+len-1]%=mod;
                }else if(i==0){
                    f[i+len-1]++;
                    f[i+len-1]%=mod;
                }
            }     
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            int len=a[j].size();
            if(i+len-1>=n)continue;
            if(str.substr(i,len)==a[j]){
                if(i&&dp[i-1]){
                    dp[i+len-1]+=dp[i-1];
                    if(dp[i+len-1]>1)dp[i+len-1]=2;
                }else if(i==0){
                    dp[i+len-1]++;
                    if(dp[i+len-1]>1)dp[i+len-1]=2;
                }
            }
        }
    }
    int ans=f[n-1];
    if(dp[n-1]==1){
        cout<<"happymorsecode"<<endl;
    }else if(dp[n-1]>1){
        cout<<"puppymousecat "<<ans<<endl;
    }else{
        cout<<"nonono"<<endl;
    }
}
posted @ 2025-05-13 21:18  Marinaco  阅读(16)  评论(0)    收藏  举报
//雪花飘落效果