• wiki with 35(dp+矩阵快速幂)


    Problem J. Wiki with 35
    Input file: standard input Time limit: 1 second
    Output file: standard output Memory limit: 256 megabytes
    从前,有一对夫妻生了五胞胎,这对夫妻为了让这五兄弟比较容易让老师记得,分别给他们取名"1"
    "3""5""7""9"。而"3""5"这两兄弟异常的聪明!
    有一天, Wiki老师为了考验"3""5"两兄弟的智力和默契程度,出了一道这样的题目:
    现在有n个连续的方格,需要他们俩往里面写上五兄弟的名字(也就是13579), 要求这n个方格
    需要填满,且只能填上他们五兄弟的名字,题目需要保证这俩兄弟的名字出现的次数一个是奇数次,一
    个是偶数次,问,一共有多少种可能性?(比如说有1个方格,那么兄弟两个可以填入3或者5,一共有2
    可能性)
    Input
    有多个测试数据输入,每行一个正整数n(1 <= n <= 109),表示连续方格的个数
    输入n = 0时结束
    Output
    每输出一个答案换一行(答案可能很大,需要对109 + 7取模)
    Sample

    standard input standard output
    1 2 0 2
    12


    思路:

    动态规划,计算方法:矩阵快速幂

    状态转移方程:(一奇一偶为满足要求的状态)

    f[i][0] = 3f[i-1][0] + 2f[i-1][1] ;不满足要求的状态

    f[i][1] = 2f[i-1][0] + 3f[i-1][1] ;满足要求的状态

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstring>
     4 
     5 using namespace std ;
     6 
     7 /*
     8     3 2
     9     2 3
    10 */
    11 
    12 const int mod = 1e9 + 7 ;
    13 typedef unsigned long long ULL ;
    14 
    15 struct node{
    16     ULL m[2][2] ;
    17 };
    18 ULL dp[2] ;
    19 int m ;
    20 
    21 
    22 node mul(node p,node q){
    23     node tmp ;
    24     memset(tmp.m,0,sizeof tmp.m) ;
    25     for(int i=0;i<2;i++){
    26         for(int j=0;j<2;j++){
    27             for(int k=0;k<2;k++){
    28                 tmp.m[i][j] = (tmp.m[i][j] + p.m[i][k] * q.m[k][j]) % mod ;
    29             }
    30         }
    31     }
    32     return tmp ;
    33 }
    34 
    35 node qmi(node q,int k){
    36     node base ;
    37     memset(base.m,0,sizeof base.m) ;
    38     for(int i=0;i<2;i++){
    39         base.m[i][i] = 1 ;
    40     }
    41     while(k){
    42         if(k&1){
    43             base = mul(base,q) ;
    44         }
    45         q = mul(q,q) ;
    46         k >>= 1 ;
    47     }
    48     return base ;
    49 }
    50 
    51 int main(){
    52     while(cin >> m, m){
    53         node a,b ;
    54         memset(a.m,0,sizeof a.m) ;
    55         memset(b.m,0,sizeof b.m) ;
    56         a.m[0][0] = a.m[1][1] = 3 ;
    57         a.m[0][1] = a.m[1][0] = 2 ;
    58         dp[0] = 1,dp[1] = 0 ;
    59         b = qmi(a,m) ;
    60         ULL ans = 0 ;
    61         for(int i=0;i<2;i++){
    62             ans += (dp[i] * b.m[1][i]) % mod ;
    63         }
    64         cout << ans << endl ;
    65     }
    66     
    67     
    68     return 0 ;
    69 }

    ...

  • 相关阅读:
    JS-Array数组对象
    JS-Math对象
    JS-Date对象
    JS-流程控制汇集
    css笔记
    CSS3-box盒布局
    css笔记
    CSS3中的animation动画
    JS-百钱买百鸡案例-for循环制作
    JS-用js的for循环实现九九乘法表以及其他算数题等
  • 原文地址:https://www.cnblogs.com/gulangyuzzz/p/12068231.html
Copyright © 2020-2023  润新知