zoukankan      html  css  js  c++  java
  • hdu_2842_Chinese Rings(矩阵快速幂)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2842

    题意:解开第k个环需要先解开前(k-2)个环,并留有第(k-1)环。问解开n环最少需要几步。

    题解:

    设f(n)表示解开第n环。 
    1. 解开n环不能一下子把n-1全解开了,否则第n个就没法拿掉了。 
    2. 得先拿掉第n个:先完成f(n-2),然后再拿掉第n环。 
    3. 然后放回前(n-2),其实这也是f(n-2),因为是一个逆的过程。 
    4. 最后就变成完成f(n-1)了,所以f(n) = f(n-2)+1 + f(n-2) + f(n-1)。

    下面是自己写的矩阵模版:

     1 #include<cstdio>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 
     4 const int maxn=3,mo=200907;//矩阵阶数,取余
     5 int N=2,n;//N为矩阵实际阶数减1
     6 
     7 struct mat{
     8     long long c[maxn][maxn];
     9     void init(){F(i,0,N)F(j,0,N)c[i][j]=0;}
    10     mat operator*(mat b){
    11         mat M; M.init();
    12         F(i,0,N)F(j,0,N)F(k,0,N)M.c[i][j]=(c[i][k]*b.c[k][j]+M.c[i][j])%mo;
    13         return M;
    14     }
    15     mat operator+(mat b){
    16         mat M; M.init();
    17         F(i,0,N)F(j,0,N)M.c[i][j]=(c[i][j]+b.c[i][j])%mo;
    18         return M;
    19     }
    20     mat operator^(int k){
    21         mat ans,tmp;ans.init();
    22         F(i,0,N)F(j,0,N)tmp.c[i][j]=c[i][j];
    23         F(i,0,N)ans.c[i][i]=1;
    24         while(k){
    25             if(k&1)ans=ans*tmp;
    26             k>>=1,tmp=tmp*tmp;
    27         }
    28         return ans;
    29     }
    30 }A[2],ans;
    31 
    32 int main(){
    33     A[0]=(mat){1,2,1,1,0,0,0,0,1},A[1]=(mat){2,0,0,1,0,0,1,0,0};
    34     while(~scanf("%d",&n),n){
    35         if(n<=2)printf("%d
    ",n);
    36         else ans=(A[0]^(n-2))*A[1],printf("%lld
    ",ans.c[0][0]);
    37     }
    38     return 0;
    39 }
    View Code



  • 相关阅读:
    java小提示:标示符常见命名规则、常用ASCII
    java程序练习:数组中随机10个数中的最大值
    java第四课:数组
    java程序练习:x进制转Y进制
    java第三课:分支结构、循环结构
    java第二课:运算符和表达式
    java第一课:环境、变量、数据类型
    00
    linux 设备驱动 nand驱动框架
    linux内核源码分析plat-form 分析
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5696119.html
Copyright © 2011-2022 走看看