• 斐波那契数列快速计算


    感觉一天时间过得挺快,而自己却没有什么收获。

    1.之前恰好看了跟快速幂乘法一样的计算大数乘法模,防止溢出,感觉挺有用的,而且用的挺多的。

    2.分析问题的能力还很差,遇到一个问题,无法正确的进行转化,怎么进行考虑,感觉自己这方面还很欠缺,这应该是通过大量做题,然后不断总结得出来的吧!毕竟题做的多了,遇到新题也就那几种套路。感觉也是挺对的,面试题的那些小套路在搞竞赛的人面前根本什么也不是,感觉这句话挺有道理的。

    3. 这次做的这道题,最后就是转化为求第n个斐波那契数,而我根本没有推导出这个。然后,之前做过怎么快速求解,一个是根据递推公式,还想是f(n)可以通过f(n/2),f(n/2 + 1), f(n/2 - 1)这几个数导出来,我也懒得记,遇到的时候就拿前几个数推导一下,很简单的。另一个方法,就是转移矩阵,快速幂求解。这个方法算是通用的方法(套路),大多数题,搞出来递推公式,可能转移条件比较多,然后搞成转移矩阵的形式,给出初始值,然后求第n个,就是求矩阵的n次幂,然后就是快速幂乘法。这个方法很重要。

    4. 忘了,这次还有一点非常重要,就是leetcode上面house robber 那题,思路倒不是挺难,但是感觉自己写的代码很丑,然后今天遇到类似的转化,就很麻烦。然后看题解,得出一种巧妙的方法。题目要求不能出现连续的1,因为是环形的,要求第一个和最后一个不能同时是1,这就增加的复杂性,你不能简单的一次递推,然后考虑这样,枚举第一个位置是0,然后从第二个位置开始,随意放,可以放还可以不放,最后的答案就是最后一个放和不放的总和,第二种情况是:第一个放,那么第二个不能放,然后从第三个开始,可以随意放,然后就转化成前面的那个问题,而且不用重复计算,最后的答案就是最后一个不能放的个数,最终把这两种情况加起来就是最后的答案。这样代码写出来,看起来也特别整齐。仔细想想,真的很巧妙!

    下面贴一下我写的求斐波那契:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 1e6 + 10;
     5 const int mod = 1e9 + 7;
     6 ll dp[maxn][2];
     7 ll n;
     8 map<ll, ll> ma;
     9 ll work(ll x) {
    10     if(x == 0) return 1;
    11     if(x < 4) return x;
    12     if(ma.count(x)) return ma[x];
    13     ll res = 0;
    14     ll t = x / 2;
    15     if(x & 1) {
    16         res = work(t) * (work(t - 1) + work(t + 1)) % mod;
    17     } else {
    18         res = work(t) * work(t) % mod + work(t - 1) * work(t - 1) % mod;
    19     }
    20     return ma[x] = res;
    21 }
    22 void solve() {
    23     cin >> n;
    24     ll res = (work(n) + work(n - 2)) % mod;
    25     cout << res << endl;
    26 }
    27 int main() {
    28     solve();
    29     /* Enter your code here. Read input from STDIN. Print output to STDOUT */   
    30     return 0;
    31 }
     1 #include<bits/stdc++.h>
     2 #define pb push_back
     3 #define FOR(i, n) for (int i = 0; i < (int)n; ++i)
     4 #define dbg(x) cout << #x << " at line " << __LINE__ << " is: " << x << endl
     5 typedef long long ll;
     6 using namespace std;
     7 typedef pair<int, int> pii;
     8 const int maxn = 1e3 + 10;
     9 const int mod = 1e9 + 7;
    10 struct mat {
    11     ll a[4];
    12     void init() {
    13         a[0] = a[3] = 1;
    14         a[1] = a[2] = 0;
    15     }
    16     mat mul(const mat &x) {
    17         mat res;
    18         res.a[0] = (a[0] * x.a[0] % mod + a[1] * x.a[2] % mod) % mod;
    19         res.a[1] = (a[0] * x.a[1] % mod + a[1] * x.a[3] % mod) % mod;
    20         res.a[2] = (a[2] * x.a[0] % mod + a[3] * x.a[2] % mod) % mod;
    21         res.a[3] = (a[2] * x.a[1] % mod + a[3] * x.a[3] % mod) % mod;
    22         return res;
    23     }
    24 };
    25 mat pow(mat a, ll b) {
    26     mat res;
    27     res.init();
    28     while(b) {
    29         if(b & 1) res = res.mul(a);
    30         a = a.mul(a);
    31         b >>= 1;
    32     }
    33     return res;
    34 }
    35 ll fb(ll n) {
    36     if(n == 0) return 1;
    37     if(n < 4) return n;
    38     mat t;
    39     t.a[0] = 0; t.a[1] = 1; t.a[2] = 1; t.a[3] = 1;
    40     t = pow(t, n);
    41     return t.a[3];
    42 }
    43 ll n;
    44 void solve() {
    45     while(cin >> n) {
    46 
    47         ll res = (fb(n) + fb(n - 2)) % mod;
    48         cout << res << endl;
    49     }
    50 }
    51 int main() {
    52     //freopen("test.in", "r", stdin);
    53     //freopen("test.out", "w", stdout);
    54     solve();
    55     return 0;
    56 }
  • 相关阅读:
    如何确定软件测试结束?
    为什么会有软件测试这一栏目?
    SQL Server 新建 数据库关系图 时弹出警告提示此数据库没有有效所有者,因此无法安装数据库关系图支持对象。
    IIS 7 实现http跳转https 重定向方法
    Centos 利用yum安装卸载软件常用命令[转载]
    VMware虚拟机中Centos7的IP地址设置方法
    【3】工厂方法模式
    【2】简单工厂模式
    【1】Singleton模式(单例模式)
    SVN提交小结
  • 原文地址:https://www.cnblogs.com/y119777/p/6063886.html
Copyright © 2020-2023  润新知