AcWing 算法提高课 状态机模型 1052. 设计密码

dp中的状态机模型会增加一维表示当前的状态。根据状态间的转移方式进行dp

 

1052. 设计密码

此题需要结合kmp和状态机模型

 

状态的定义是 dp[i][j]表示遍历到字母i,且匹配了长度为j的模板串,匹配模板串的长度即为状态。

状态的转移根据i-1位的匹配长度,以及i位的字母,计算i位的匹配长度。

根据kmp数组p,i-i位的匹配长度j(遍历)以及i位的字母(遍历),计算可以转移到的i位置的匹配长度,然后dp求和。

代码如下

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;

LL dp[60][60];
int p[60];
int main()
{
    int n;
    cin>>n;
    string str;
    cin>>str;
    int m=str.size();
    str='0'+str;

    p[0]=0;
    int j=0;
    for(int i=2;i<=m;i++)
    {
        while(j&&str[i]!=str[j+1])
            j=p[j];
        if(str[i]==str[j+1]) j++;
        p[i]=j;
    }
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            for(char ch='a';ch<='z';ch++)
            {
                int tmp=j;
                while(tmp&&ch!=str[tmp+1]) tmp=p[tmp];
                
                if(ch==str[tmp+1]) 
                {
                    dp[i][tmp+1]+=dp[i-1][j];
                    dp[i][tmp+1]%=1000000007;
                }
                else
                {
                    dp[i][0]+=dp[i-1][j];
                    dp[i][0]%=1000000007;
                }
            }
            
        }
    }
    LL res=0;
    for(int i=0;i<m;i++)
    {
        res+=dp[n][i];
        res%=1000000007;
    }
    cout<<res<<endl;
}
View Code

 

posted @ 2022-06-08 19:34  80k  阅读(42)  评论(0)    收藏  举报