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个连续的方格,需要他们俩往里面写上五兄弟的名字(也就是1、 3、 5、 7、 9), 要求这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 }

 

 

...

上一篇:git commit message规范与约束(全局安装)


下一篇:Elasticsearch学习笔记之—分词器 analyzer