zoukankan      html  css  js  c++  java
  • poj3420_找规律+矩阵快速幂

    题目链接:http://poj.org/problem?id=3420

    题意:用1 X 2的矩形填充4 X n的矩形,共有多少种不同方法。

    思路:听说有公式,推了一下

    如果n-1行填满的话,第n行只有一种情况,如果n-2行填满的话,有4种情况;

    如果n-3行填满的话,有2种情况; 

    如果n-4行填满的话,有3种情况; 

    如果n-5行填满的话,有2种情况; 

    如果n-6行填满的话,有3种情况; 

    ...

    f[n] = f[n-1] + 4*f[n-2] + 2 * [ f[n-3] + f[n-5] + f[n-7] +.... ] + 3 *  [ f[n-4] + f[n-6] + f[n-8] +.... ] ; (1)

    f[n - 2] = f[n-3] + 4*f[n-4] + 2 * [ f[n-5] + f[n-7] + f[n-9] +.... ] + 3 *  [ f[n-6] + f[n-8] + f[n-10] +.... ] ; (2)

    (1) - (2) 化简得  f[n] = f[n-1] + 5f[n-2] + f[n-3] - f[n-4]

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <set>
     8 #include <map>
     9 #include <queue>
    10 #include <vector>
    11 #define INF 0x3f3f3f3f
    12 using namespace std;
    13 int a[4], n, m;
    14 typedef long long LL;
    15 struct data{
    16     LL mat[4][4];
    17 };
    18 data mul(data a, data b)
    19 {
    20     data res;
    21     memset(res.mat, 0, sizeof(res.mat));
    22     for(int i = 0; i < 4; i++)
    23         for(int j = 0; j < 4; j++)
    24             for(int i2 = 0; i2 < 4; i2++)
    25                 res.mat[i][j] = ((res.mat[i][j]+(a.mat[i][i2]*b.mat[i2][j])%m)%m+m)%m;
    26     return res;
    27 }
    28 int main()
    29 {
    30     a[0] = 1, a[1] = 1, a[2] = 5, a[3] = 11;
    31     while(~scanf("%d %d", &n, &m) && n + m) {
    32         if(n < 4) {
    33             printf("%d
    ", a[n] % m);
    34             continue;
    35         }
    36         n -= 3;
    37         data base, res;
    38         memset(base.mat, 0, sizeof(base.mat));
    39         memset(res.mat, 0, sizeof(res.mat));
    40         for(int i = 0; i < 4; i++)
    41             base.mat[i][i] = 1;
    42         res.mat[0][0] = 1, res.mat[0][1] = 5; 
    43         res.mat[0][2] = 1, res.mat[0][3] = -1;
    44         res.mat[1][0] = 1, res.mat[2][1] = 1;
    45         res.mat[3][2] = 1;
    46         while(n) {
    47             if(n % 2)
    48                 base = mul(res, base);
    49             res = mul(res, res);
    50             n >>= 1;
    51         } 
    52         LL res2 = 0;   
    53         for(int i = 0; i < 4; i++)    
    54             res2 = (res2 + (base.mat[0][i] * a[3 - i])%m)%m;
    55         printf("%lld
    ", res2);
    56     }
    57     return 0;
    58 }

    下面是某个大牛写的代码

     1 //某个低调的大牛写的
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <string>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <ctime>
    10 #include <cmath>
    11 #include <queue>
    12 #include <set>
    13 #include <map>
    14 using namespace std;
    15 #define Fill(x, y) memset((x), (y), sizeof(x))
    16 #define Rep(i, x, y) for(int i = x; i <= y; ++i)
    17 #define Dow(i, x, y) for(int i = x; i >= y; --i)
    18 typedef long long LL;
    19 typedef pair <int, int> P;
    20 typedef pair <LL, LL> PLL;
    21 const LL inf = 1e18;
    22 const int N = 1e5 + 10;
    23 int GCD(int a, int b) {
    24     return b ? GCD(b, a % b) : a;
    25 }
    26 int LCM(int a, int b) {
    27     return a * b / GCD(a, b);
    28 }
    29 struct data {
    30     LL mat[5][5];
    31 };
    32 
    33 LL f[N] , mod;
    34 
    35 data operator *(data a, data b) {
    36     data res;
    37     for(int i = 1 ; i <= 4 ; ++i) {
    38         for(int j = 1 ; j <= 4 ; ++j) {
    39             res.mat[i][j] = 0;
    40             for(int k = 1 ; k <= 4 ; ++k) {
    41                 res.mat[i][j] = ((a.mat[i][k] * b.mat[k][j] % mod + res.mat[i][j]) % mod + mod) % mod;
    42             }
    43         }
    44     }
    45     return res;
    46 }
    47 
    48 data operator ^(data a , LL n) {
    49     data res;
    50     for(int i = 1 ; i <= 4 ; ++i) {
    51         for(int j = 1 ; j <= 4 ; ++j) {
    52             res.mat[i][j] = (i == j);
    53         }
    54     }
    55     while(n) {
    56         if(n & 1)
    57             res = res * a;
    58         a = a * a;
    59         n >>= 1;
    60     }
    61     return res;
    62 }
    63 
    64 int main()
    65 {
    66     f[1] = 1 , f[2] = 5 , f[3] = 11 , f[4] = 36;
    67     LL n;
    68     while(cin >> n >> mod && (mod || n)) {
    69         if(mod == 1) {
    70             cout << 0 << endl;
    71             continue;
    72         }
    73         if(n <= 4) {
    74             cout << f[n] % mod << endl;
    75             continue;
    76         }
    77         data a , res;
    78         for(int i = 1 ; i <= 4 ; ++i) {
    79             for(int j = 1 ; j <= 4 ; ++j) {
    80                 a.mat[i][j] = 0;
    81                 res.mat[i][j] = 0;
    82             }
    83             res.mat[i][1] = f[5 - i] % mod;
    84         }
    85         a.mat[1][1] = a.mat[2][1] = a.mat[3][2] = a.mat[4][3] = a.mat[1][3] = 1;
    86         a.mat[1][2] = 5 , a.mat[1][4] = -1;
    87         a = a ^ (n - 4);
    88         res = a * res;
    89         cout << (res.mat[1][1] + mod) % mod << endl;
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    基于DCT系数的实时监控中运动目标检测
    智能视频分析中的光照强度突然变化的处理方法
    《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他。
    mysql流程控制语句
    mysql中变量
    mysql中触发器
    mysql中(存储)函数
    mysql中存储过程
    mysql中视图
    mysql中一些表选项
  • 原文地址:https://www.cnblogs.com/luomi/p/5689542.html
Copyright © 2011-2022 走看看