• BZOJ 1009 [HNOI2008]GT考试 矩阵乘法+DP


    题解:

    dp[i][j]表示长度为i,匹配了j个的方案数,压缩成矩阵,转移即可。

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <algorithm>
      6 
      7 #define SIZE 21
      8 
      9 using namespace std;
     10 
     11 struct MT
     12 {
     13     int x,y;
     14     int mt[SIZE][SIZE];
     15     void prt()
     16     {
     17         for(int i=0;i<=x;i++){
     18             for(int j=0;j<=y;j++)
     19                 printf("%d  ",mt[i][j]);puts("");}
     20     }
     21 }ans,zy;
     22 
     23 int n,m,mod;
     24 char a[SIZE],b[SIZE],c[SIZE];
     25 int len,lenc;
     26 
     27 inline MT operator *(MT a,MT b)
     28 {
     29     MT c; memset(c.mt,0,sizeof c.mt);
     30     c.x=a.x; c.y=b.y;
     31     for(int i=0;i<=c.x;i++)
     32         for(int j=0;j<=c.y;j++)
     33         {
     34             for(int k=0;k<=a.y;k++)
     35                 c.mt[i][j]+=a.mt[i][k]*b.mt[k][j];
     36             c.mt[i][j]%=mod;
     37         }
     38     return c;
     39 }
     40 
     41 inline void read()
     42 {
     43     scanf("%d%d%d",&n,&m,&mod);
     44     scanf("%s",a+1);
     45 }
     46 
     47 inline void getstring(int x,int y)
     48 {
     49     len=0;
     50     for(int i=1;i<=x;i++) b[++len]=a[i];
     51     b[++len]=y;
     52 }
     53 
     54 inline void getsuf(int x)
     55 {
     56     lenc=0;
     57     for(int i=len-x+1;i<=len;i++) c[++lenc]=b[i];
     58 }
     59 
     60 inline bool check()
     61 {
     62     for(int i=1;i<=lenc;i++)
     63         if(a[i]!=c[i]) return false;
     64     return true;
     65 }
     66 
     67 inline void prep()
     68 {
     69     for(int i=0;i<m;i++)
     70         for(int j=0;j<=9;j++)
     71         {
     72             getstring(i,j+'0');
     73             for(int k=len;k>=0;k--)
     74             {
     75                 if(k==m)
     76                 {
     77                     getsuf(k);
     78                     if(check()) break;
     79                     else continue;
     80                 }
     81                 getsuf(k);
     82                 if(check()) {zy.mt[k][i]++;break;}//转移反过来写!! 
     83             }
     84         }
     85     zy.x=zy.y=m-1;
     86     ans.x=m-1; ans.y=0;
     87     ans.mt[0][0]=1;
     88 }
     89 
     90 inline void go()
     91 {
     92     prep();
     93     while(n)
     94     {
     95         if(n&1) ans=zy*ans;
     96         zy=zy*zy;
     97         n>>=1;
     98     }
     99     int res=0;
    100     for(int i=0;i<m;i++) res+=ans.mt[i][0];
    101     cout<<res%mod<<endl;
    102 }
    103 
    104 int main()
    105 {
    106     read(),go();
    107     return 0;
    108 }
  • 相关阅读:
    Java实现 LeetCode 784 字母大小写全排列(DFS)
    Java实现 LeetCode 784 字母大小写全排列(DFS)
    Java实现 LeetCode 783 二叉搜索树节点最小距离(遍历)
    Java实现 LeetCode 783 二叉搜索树节点最小距离(遍历)
    Java实现 LeetCode 783 二叉搜索树节点最小距离(遍历)
    Java实现 LeetCode 781 森林中的兔子(分析题)
    一种机制,与js类似
    图片热区
    我对 aspnetpager和repeater以及查询条件的封装
    我对webform的整改。
  • 原文地址:https://www.cnblogs.com/proverbs/p/2945053.html
Copyright © 2020-2023  润新知