zoukankan      html  css  js  c++  java
  • HDU 6185 Covering

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

    题目大意:给一个N*4的方格矩阵,现在用1*2或2*1的方格铺满它,问有多少种方法。结果对1e9+7取模。N<=1e18

    解题思路:一看N很大就能够想到需要一个logN级别的算法。这个题目与我昨天写的这个题目:http://www.cnblogs.com/bolderic/p/7487674.html 基本上一样,但是不同的是N和M的取值。如果依然用状态压缩的动态规划解法显然会超时。但是这样考虑,对于N列矩阵来说,放的方法实际上有五种分别是:

             

    那么可以构造四个形状来递推:

          

    从前到后设为A,B,C,D,则有:

    A(n) = A(n - 1) + B(n - 1) + 2D(n - 1) + A(n - 2), A(0) = 1, A(1) = 1

    B(n) = A(n - 1) + C(n - 1), B(0) = 0, B(1) = 1

    C(n) = B(n - 1), C(0)= 0, C(1) = 0

    D(n) = D(n - 1)  + A(n - 1), D(0) = 0, D(1) = 1

    然后就可以构造一个5*5的矩阵计算:

    A(n)   1 1 0 2 1  A(n - 1)

    B(n)   1 0 1 0 0  B(n - 1)

    C(n) =   0 1 0 0 0 *  C(n - 1)

    D(n)   1 0 0 1 0  D(n - 1)

    A(n - 1)   1 0 0 0 0  A(n - 2)

    代码:

     1 typedef vector<ll> vec;
     2 typedef vector<vec> mat;
     3 ll n;
     4 
     5 mat mul(mat &A, mat &B){
     6     mat C(A.size(), vec(B[0].size()));
     7     for(int i = 0; i < A.size(); i++){
     8         for(int k = 0; k < B.size(); k++){
     9             for(int j = 0; j < B[0].size(); j++){
    10                 C[i][j] = (C[i][j] + A[i][k] % mod * B[k][j]) % mod;
    11             }
    12         }
    13     }
    14     return C;
    15 }
    16 mat pow(mat A, ll n){
    17     mat B(A.size(), vec(A.size()));
    18     for(int i = 0; i < A.size(); i++){
    19         B[i][i] = 1;
    20     }
    21     while(n > 0){
    22         if(n & 1) B = mul(B, A);
    23         A = mul(A, A);
    24         n >>= 1;
    25     }
    26     return B;
    27 }
    28 void solve(){
    29     mat A(5, vec(5));
    30     A[0][0] = 1; A[0][1] = 1; A[0][2] = 0; A[0][3] = 2; A[0][4] = 1;
    31     A[1][0] = 1; A[1][1] = 0; A[1][2] = 1; A[1][3] = 0; A[1][4] = 0;
    32     A[2][0] = 0; A[2][1] = 1; A[2][2] = 0; A[2][3] = 0; A[2][4] = 0;
    33     A[3][0] = 1; A[3][1] = 0; A[3][2] = 0; A[3][3] = 1; A[3][4] = 0;
    34     A[4][0] = 1; A[4][1] = 0; A[4][2] = 0; A[4][3] = 0; A[4][4] = 0;
    35     A = pow(A, n - 1);
    36     ll ans = A[0][0] + A[0][1] + A[0][3] + A[0][4];
    37     printf("%lld
    ", ans % mod);
    38 }
    39 int main(){
    40     while(scanf("%lld", &n) != EOF){
    41         solve();
    42     }
    43 }

    题目:

    Covering

    Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 643    Accepted Submission(s): 281


    Problem Description
    Bob's school has a big playground, boys and girls always play games here after school.

    To protect boys and girls from getting hurt when playing happily on the playground, rich boy Bob decided to cover the playground using his carpets.

    Meanwhile, Bob is a mean boy, so he acquired that his carpets can not overlap one cell twice or more.

    He has infinite carpets with sizes of 1×2 and 2×1, and the size of the playground is 4×n.

    Can you tell Bob the total number of schemes where the carpets can cover the playground completely without overlapping?
     
    Input
    There are no more than 5000 test cases. 

    Each test case only contains one positive integer n in a line.

    1n1018
     
    Output
    For each test cases, output the answer mod 1000000007 in a line.
     
    Sample Input
    1 2
     
    Sample Output
    1 5
     
    Source
     

       

  • 相关阅读:
    计算机中的那些缩写词
    Linux 下dns的搭建
    html中的定位
    编程基础之流程控制
    linux中kvm的安装及快照管理
    zabbix 中监控windows 的typepref中的值
    详解Linux交互式shell脚本中创建对话框实例教程_linux服务器
    rhel7 单用户修改root密码
    Linux vim编辑器使用详解
    Linux下用ftp更新web内容!
  • 原文地址:https://www.cnblogs.com/bolderic/p/7489151.html
Copyright © 2011-2022 走看看