zoukankan      html  css  js  c++  java
  • bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009

    首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串。

    为了dp,需要记录第 i 个位置的后缀已经有几位和模式串的前几位吻合了。

    所以想到可以转移到 j+1 或 0 。

    但其实不一定是0,因为可能和前面的接上。这里就要用kmp了!

    注意可以和很多位置接上的时候,应该和最长的那个接上,而不是和每个 nxt 都接上,也不是什么能选择的。

    知道了当前 j 能转移到哪些 j ,就可以矩阵优化了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=25;
    int n,m,mod,nxt[N],prn,ch[N];
    struct Matrix{
      int a[N][N];
      Matrix(){memset(a,0,sizeof a);}
      Matrix operator * (const Matrix &b)const
      {
        Matrix c;
        for(int i=0;i<m;i++)//<m is enough
          for(int k=0;k<m;k++)
        for(int j=0;j<m;j++)
          (c.a[i][j]+=a[i][k]*b.a[k][j]%mod)%=mod;
        return c;
      }
    }r,ans;
    void getnxt()
    {
      for(int i=2;i<=m;i++)//i=2,or nxt[1]=1
        {
          int k;
          for(k=nxt[i-1];ch[k+1]!=ch[i]&&k;k=nxt[k]);
          nxt[i]=k+(ch[k+1]==ch[i]);
        }
      for(int i=0;i<m;i++)//i=0 //<m is enough
        {
          for(int j=0;j<=9;j++)
        {
          int k;
          for(k=i;k&&ch[k+1]!=j;k=nxt[k]);//k=i!!
          if(ch[k+1]==j)r.a[i][k+1]++;//only keep 1,keep the longest
          else r.a[i][0]++;
          //        if(ch[k+1]==j)r.a[i][k+1]++;
          //      if(ch[1]==j)r.a[i][1]++;// when k=0
          //      else r.a[i][0]++;//
        }
          //      if(i&&i!=m)r.a[i][i+1]++;//don't forget, and i!=0
        }
    }
    int main()
    {
      scanf("%d%d%d",&n,&m,&mod);
      for(int i=1;i<=m;i++)scanf("%1d",&ch[i]);
      getnxt();
      //  for(int i=0;i<m;i++)ans.a[i][i]=1;//!!
      ans.a[0][0]=1;
      while(n){if(n&1)ans=ans*r;r=r*r;n>>=1;}
      for(int i=0;i<m;i++)(prn+=ans.a[0][i])%=mod;
      printf("%d
    ",prn);
      return 0;
    }
  • 相关阅读:
    LintCode "Maximum Gap"
    LintCode "Wood Cut"
    LintCode "Expression Evaluation"
    LintCode "Find Peak Element II"
    LintCode "Remove Node in Binary Search Tree"
    LintCode "Delete Digits"
    LintCode "Binary Representation"
    LeetCode "Game of Life"
    LintCode "Coins in a Line"
    LintCode "Word Break"
  • 原文地址:https://www.cnblogs.com/Narh/p/9260150.html
Copyright © 2011-2022 走看看