zoukankan      html  css  js  c++  java
  • [BZOJ1009]GT考试

    1009: [HNOI2008]GT考试

    Time Limit: 1 Sec  Memory Limit: 162 MB

    Description

      阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
    他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为
    0

    Input

      第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000

    Output

      阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

    Sample Input

    4 3 100
    111

    Sample Output

    81
     
    题解:
     
    KMP套上dp还真是第一次见……想的时候想歪了
    f[i][j]为前i位准考证,后j位和不吉利数字的前j位匹配时前i位的匹配方案数,那么ans=∑f[n][i],i∈[0,m-1].
    先用kmp跑出fail数组
    为了便于处理,f[i][j]同时满足不重复,即f[i][fail[j]]中不包含f[i][j]的方案
    比如对于不吉利数字为123124的情况,f[i][2](*****12)中就不能包含f[i][5](**12312)的方案
    考虑转移,显然f[i][j]只能由f[i-1][k]转移过来
    考虑对于f[i-1][k]的后k位,那么我们可以枚举填上的每一种可能数字(0到9),看填上之后会转移到f[i][j]的哪一个j,这里通过前面的fail数组跳跃
    还是对于123124这个例子,容易看出(手玩一下)f[i][3]=f[i-1][2](变成***123)+f[i-1][5](变成***123123)
    意思就是匹配不吉利数字前3位可以通过匹配前两位填上3转移过来,也可以通过前五位填上3转移过来
    同时,填上数字之后不能非法,比如不吉利数字为123123,f[i][3]=f[i-1][2](变成***123),而没有再加上f[i][5](变成***123123)
    初始时,f[0][0]=1。
    然后我们考虑,f[i][j]的式子是一个线性递推式,我们就可以打个矩阵乘法优化了,这里不再赘述方法
    代码见下:
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 using namespace std;
     5 int A[25][25],B[25][25],tmp[25][25];
     6 int n,m,k,fail[25];char s[25];
     7 inline void quick_mod(int mi)
     8 {
     9     for(int i=0;i<25;i++)B[i][i]=1;
    10     while(mi)
    11     {
    12         if(mi&1)
    13         {
    14             memset(tmp,0,sizeof(tmp));
    15             for(int i=1;i<=m;i++)
    16                 for(int j=1;j<=m;j++)
    17                     for(int u=1;u<=m;u++)
    18                         tmp[i][j]=(tmp[i][j]+B[i][u]*A[u][j])%k;
    19             for(int i=1;i<=m;i++)
    20                 for(int j=1;j<=m;j++)
    21                     B[i][j]=tmp[i][j];
    22         }
    23         mi>>=1;
    24         memset(tmp,0,sizeof(tmp));
    25         for(int i=1;i<=m;i++)
    26             for(int j=1;j<=m;j++)
    27                 for(int u=1;u<=m;u++)
    28                     tmp[i][j]=(tmp[i][j]+A[i][u]*A[u][j])%k;
    29         for(int i=1;i<=m;i++)
    30             for(int j=1;j<=m;j++)
    31                 A[i][j]=tmp[i][j];
    32     }
    33 }
    34 inline void get_fail()
    35 {
    36     for(int i=1,j=fail[i];i<m;i++,j=fail[i])
    37     {
    38         while(j&&s[i]!=s[j])j=fail[j];
    39         fail[i+1]=(s[i]==s[j])?j+1:0;
    40     }
    41     for(int i=0;i<m;i++)
    42         for(int j='0';j<='9';j++)
    43         {
    44             int u=i;
    45             while(u&&s[u]!=j)u=fail[u];
    46             if(s[u]==j)u++;
    47             if(u!=m)A[i+1][u+1]=(A[i+1][u+1]+1)%k;
    48         }
    49 }
    50 int main()
    51 {
    52     scanf("%d%d%d",&n,&m,&k);
    53     scanf("%s",s);int ans=0;
    54     get_fail();quick_mod(n);
    55     for(int i=1;i<=m;i++)ans=(ans+B[1][i])%k;
    56     printf("%d",ans);
    57 }
    BZOJ1009
  • 相关阅读:
    Android Studio没有 Build Bundle(s)/Apk(s)选项或者Make Project没有反应
    typescript遍历Map
    Cocos Creator的项目优化问题
    Cocos Creator 常用优化技巧汇总
    CocosCreator客户端优化系列(四):CPU占用以及性能优化
    CocosCreator客户端优化系列(三):内存优化
    CocosCreator客户端优化系列(二):渲染优化
    CocosCreator客户端优化系列(一):加载优化(下)
    CocosCreator客户端优化系列(一):加载优化(上)
    cocos creator性能优化--Prefab加载优化
  • 原文地址:https://www.cnblogs.com/LadyLex/p/7061005.html
Copyright © 2011-2022 走看看