[P4965]薇尔莉特的打字机 题解
既然是博客园的第一篇题解,那就搬点有意义的吧
解题思路:递推
一道很好的锻炼推式子能力的题,也是本蒟蒻第一道一遍过的紫题。
既然是递推,那就先定义一下状态:
很明显,我们需要分两种情况讨论:这次操作为添加字符或退格。
先分析第一种情况,添加字符。这个时候又要分两种小情况:
当这个字符在操作中是第一次出现时,把它接在任何已有的字符串后面,都不会重复。所以
当这个字符在操作中已经出现过时,设它上次出现处为
第二种情况,退格。我们会发现,得到的全部都是重复的字符串,只有一种情况除外:此前的操作,所有添加字符都没执行,所有退格都有执行,这个时候就会多出一种情况:原有的字符串去掉末尾长度为
还需要注意的是,举个例子,原有字符串为 AB,操作uB。这个时候答案不是
还有一处值得一提:本人第一次写的时候,当有添加字符的操作时,把之前所有出现过的字符所产生的重复都算上了,然后就很容易地没过样例。想了一下,是因为前一个相同字符之前所产生的影响都包含在了其中,所以不用统计。
code:
点击查看代码
int n,m,cnt[27],f[maxn];
char s[maxn],t[maxn];
void solve(){
scanf("%d%d%s%s",&n,&m,s+1,t+1);
f[0]=1;//别忘了初始化
for(int i=1,k=0;i<=m;i++){
if(t[i]=='u'){
if(k<n)f[i]=f[i-1]+1;
else f[i]=f[i-1];
if(k<n)cnt[s[n-k]-'A'+1]++;
k++;
}else{
int x=t[i]-'A'+1;
f[i]=f[i-1]*2%mod;
f[i]=(f[i]-cnt[x]+mod)%mod;
cnt[x]=f[i-1];
}
}
printf("%d",f[m]);
}