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;
}
}

浙公网安备 33010602011771号