zoukankan      html  css  js  c++  java
  • bzoj 1009 DP 矩阵优化

    原来的DP:

    dp[i][j]表示长度为i的合法串,并且它的长度为j的后缀是给定串的长度为j的前缀。

    转移:

    i==0

    dp[0][0] = 1 dp[0][1~m-1] = 0

    i>=1

    dp[i][0] = dp[i-1][0]*10-dp[i-1][m-1]

    dp[i][1] = dp[i-1][0]-(a[m]==a[1])*dp[i-1][m-1]

    dp[i][2] = dp[i-1][1]-(a[m-1~m]==a[1~2])*dp[i-1][m-1]

    dp[i][3] = dp[i-1][2]-(a[m-2~m]==a[1~3])*dp[i-1][m-1]

    ...

    dp[i][m-1] = dp[i-1][m-2]-(a[2~m]==a[1~m-1])*dp[i-1][m-1]

     (a[i~j]==a[p~q]表示原串的[i,j]区间与[p,q]区间是否相等)

    然后就是一般的矩阵求线性递推的东西了。

     1 /**************************************************************
     2     Problem: 1009
     3     User: idy002
     4     Language: C++
     5     Result: Accepted
     6     Time:48 ms
     7     Memory:804 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11  
    12  
    13 int n, m, mod;
    14 int a[20];
    15 bool mat[20];
    16  
    17 struct Matrix {
    18     int a[20][20];
    19     void make_zero() {
    20         for( int i=0; i<m; i++ )
    21             for( int j=0; j<m; j++ )
    22                 a[i][j] = 0;
    23     }
    24     void make_unit() {
    25         for( int i=0; i<m; i++ ) {
    26             for( int j=0; j<m; j++ )
    27                 a[i][j] = 0;
    28             a[i][i] = 1;
    29         }
    30     }
    31     Matrix operator*( const Matrix & B ) const {
    32         const Matrix & A = *this;
    33         Matrix C;
    34         C.make_zero();
    35         for( int i=0; i<m; i++ )
    36             for( int j=0; j<m; j++ ) 
    37                 for( int k=0; k<m; k++ ) {
    38                     C.a[i][j] += A.a[i][k]*B.a[k][j];
    39                     C.a[i][j]%=mod;
    40                 }
    41         return C;
    42     }
    43 };
    44  
    45 void prep() {
    46     for( int i=0; i<m-1; i++ ) {
    47         mat[i] = true;
    48         for( int j=0; j<=i; j++ )
    49             if( a[j]!=a[m-i-1+j] ) {
    50                 mat[i] = false;
    51                 break;
    52             }
    53     }
    54 }
    55 Matrix mpow( Matrix a, int b ) {
    56     Matrix rt;
    57     rt.make_unit();
    58     for( ; b; b>>=1,a=a*a )
    59         if( b&1 ) rt=rt*a;
    60     return rt;
    61 }
    62  
    63 void work() {
    64     Matrix a;
    65     a.make_zero();
    66     a.a[0][0] = 10;
    67     a.a[0][m-1] = -1;
    68     for( int i=1; i<m; i++ ) {
    69         a.a[i][i-1] = 1;
    70         a.a[i][m-1] = -mat[i-1];
    71     }
    72     a = mpow(a,n);
    73     int ans = (a.a[0][0]%mod+mod)%mod;
    74     printf( "%d
    ", ans );
    75 }
    76  
    77 int main() {
    78     scanf( "%d%d%d", &n, &m, &mod );
    79     char ch;
    80     while( scanf( "%[
     ]", &ch ) );
    81     for( int i=0; i<m; i++ ) {
    82         scanf( "%c", &ch );
    83         a[i] = ch-'0';
    84     }
    85     prep();
    86     work();
    87 }
    View Code
  • 相关阅读:
    IDEA创建Javaweb工程
    配置Info.plist (设置状态栏样式、自定义定位时系统弹出的提示语、配置3DTouch应用快捷菜单)
    关于IQKeyBoardManager挤出导航栏的解决方案
    iOS应用内跳转系统设置相关界面的方法
    解决xcode打开时loading假死的问题
    iOS图片按比例显示
    iOS开发-UITableView顶部图片下拉放大
    自定义按钮 图片+文字
    iOS开发-NSOperation与GCD区别
    iOS开发-UINavigationBar透明设置
  • 原文地址:https://www.cnblogs.com/idy002/p/4295745.html
Copyright © 2011-2022 走看看