PTA一步两步
一、题目描述
二、解题思路
这个题用常规的dp是行不通的,应为数据量太大了。那么应该怎么优化呢。
答案是采用矩阵优化
我们构造一个这样的矩阵,然后乘以以F1、F2构造得2*1的矩阵
为了发现规律,我们再乘一次
我们发现每一次左乘一个我们构造得这样的矩阵,我们都会得到下一个数列。分析下标关系可知,我们只需要左边的矩阵左乘n-2次,即可以得到Fn。因为是左乘n-2次,我们可以用快速幂进行优化,类似于以前求指数的形式。
三、代码实现
1 #include "bits/stdc++.h" 2 #define PII pair<int,int> 3 #define rep(i,z,n) for(int i = z;i <= n; i++) 4 #define per(i,n,z) for(int i = n;i >= z; i--) 5 #define ll long long 6 #define db double 7 #define vi vector<int> 8 #define debug(x) cerr << "!!!" << x << endl; 9 using namespace std; 10 //从某个串中把某个子串替换成另一个子串 11 string& replace_all(string& src, const string& old_value, const string& new_value) { 12 // 每次重新定位起始位置,防止上轮替换后的字符串形成新的old_value 13 for (string::size_type pos(0); pos != string::npos; pos += new_value.length()) { 14 if ((pos = src.find(old_value, pos)) != string::npos) { 15 src.replace(pos, old_value.length(), new_value); 16 } 17 else break; 18 } 19 return src; 20 } 21 inline ll read() 22 { 23 ll s,r; 24 r = 1; 25 s = 0; 26 char ch = getchar(); 27 while(ch < '0' || ch > '9'){ 28 if(ch == '-') 29 r = -1; 30 ch = getchar(); 31 } 32 while(ch >= '0' && ch <= '9'){ 33 s = (s << 1) + (s << 3) + (ch ^ 48); 34 ch = getchar(); 35 } 36 return s * r; 37 } 38 inline void write(ll x) 39 { 40 if(x < 0) putchar('-'),x = -x; 41 if(x > 9) write(x / 10); 42 putchar(x % 10 + '0'); 43 } 44 const int N = 2; 45 const int mod = 1e9+7; 46 void Multi_Matrix(ll a[][N + 1],ll b[][N + 1],int prow,int pcol,int lrow,int lcol) 47 { 48 //pcol是前面矩阵的列 49 //lrow是后面矩阵的行 50 if(pcol != lrow){ 51 cout << "error" << endl; 52 return; 53 } 54 ll c[N + 1][N + 1]; 55 memset(c,0,sizeof(c)); 56 for(int i = 1;i <= prow;i++) 57 for(int j = 1;j <= lcol;j++) 58 for(int k = 1;k <= pcol;k++) 59 c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % mod; 60 61 //相乘的结果赋值给原来的矩阵 62 for(int i = 1;i <= prow;i++) 63 for(int j = 1;j <= lcol;j++) 64 a[i][j] = c[i][j]; 65 } 66 //矩阵快速幂 67 void Qpow_Matrix(ll a[N + 1][N + 1],ll n) 68 { 69 ll res[N + 1][N + 1]; 70 for(int i = 1;i <= N;i++) 71 for(int j = 1;j <= N;j++) 72 res[i][j] = 1; 73 while(n){ 74 if(n & 1) 75 Multi_Matrix(res,a,N,N,N,N); 76 Multi_Matrix(a,a,N,N,N,N); 77 n >>= 1; 78 } 79 //把相乘后的答案还给原矩阵 80 for(int i = 1;i <= N;i++) 81 for(int j = 1;j <= N;j++) 82 a[i][j] = res[i][j]; 83 } 84 int main() 85 { 86 ll n; 87 n = read(); 88 if(n == 1 || n == 2){ 89 cout << 1 << endl; 90 return 0; 91 } 92 ll a[N + 1][N + 1]; 93 a[1][1] = 1;a[1][2] = 1; 94 a[2][1] = 1;a[2][2] = 0; 95 Qpow_Matrix(a,n - 2); 96 cout << a[1][1] << endl; 97 return 0; 98 }
本文来自博客园,作者:{scanner},转载请注明原文链接:{https://home.cnblogs.com/u/scannerkk/}