zoukankan      html  css  js  c++  java
  • week4-D-Q老师染砖

    Description

    衣食无忧的 Q老师 有一天突发奇想,想要去感受一下劳动人民的艰苦生活。

    具体工作是这样的,有 N 块砖排成一排染色,每一块砖需要涂上红、蓝、绿、黄这 4 种颜色中的其中 1 种。且当这 N 块砖中红色和绿色的块数均为偶数时,染色效果最佳。

    为了使工作效率更高,Q老师 想要知道一共有多少种方案可以使染色效果最佳,你能帮帮他吗?

    Input

    第一行为 T,代表数据组数。(1 ≤ T ≤ 100)

    接下来 T 行每行包括一个数字 N,代表有 N 块砖。(1 ≤ N ≤ 1e9)

    Output

    输出满足条件的方案数,答案模 10007。

    Sample Input

    2
    1
    2

    Sample Output

    2
    6

    思路:

    连续格子染色,很明显有子结构的性质,可以考虑 DP ,但是 n 很大,因此考虑矩阵快速幂优化 DP。
    令 A[i] ,B[I] , C[i]表示 i 个格子,红绿均为偶数、均为奇数、有一个为偶数的染色方案数 。
    则DP 转移方程 :
    A[i] = 2 * A[i-1] + C[i-1]
    B[i] = 2 * B[i-1] + C[i-1]
    C[i] = 2 * A[i-1] + 2 * B[i-1] + 2 * C[i-1]
    不难看出,A[1]=2,B[1]=0,C[1]=2

    矩阵快速幂

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int  m=10007;
     5 /*
     6        2  0  1
     7 [i] =  0  2  1   [i-1]
     8        2  2  2
     9 
    10 */
    11 int n;
    12 
    13 struct Matrix {
    14     int v[3][3];
    15     Matrix() 
    16     {
    17         memset(v, 0, sizeof(v));
    18     }
    19     
    20     Matrix operator *(Matrix const &b) const 
    21     {
    22         Matrix re;
    23         for (int i = 0; i < 3; i++)
    24         {
    25             for (int j = 0; j < 3; j++)
    26             {
    27                 re.v[i][j] = 0;
    28                 for (int k = 0; k < 3; k++)
    29                 {
    30                     re.v[i][j] += (v[i][k]*b.v[k][j])%m;    
    31                 }
    32                 re.v[i][j] %= m;
    33             }
    34                 
    35         }            
    36         return re;
    37     }
    38     
    39 };
    40 void init(Matrix& m){
    41     m.v[0][0]=m.v[1][1]=m.v[2][2]=m.v[2][0]=m.v[2][1]=2;
    42     m.v[0][1]=m.v[1][0]=0;
    43     m.v[0][2]=m.v[1][2]=1;        
    44 }
    45 
    46 Matrix quick_pow(Matrix a, int x) 
    47 {
    48     Matrix ret ;
    49     ret.v[0][0]=2;
    50     ret.v[1][0]=0;
    51     ret.v[2][0]=2;
    52     while (x) {
    53         if (x & 1)
    54             ret = a * ret;
    55         a = a * a;
    56         x >>= 1;
    57     }
    58     return ret;
    59 } 
    60 
    61 int main()
    62 {
    63     int T;
    64     cin>>T;
    65     while(T--)
    66     {
    67         cin>>n;
    68         Matrix a;
    69         init(a);
    70         a = quick_pow(a, n-1);
    71         cout<<a.v[0][0]<<endl;
    72     }
    73  } 
  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/13053747.html
Copyright © 2011-2022 走看看