Kai’blog

技术博客

【递推】月落乌啼算钱

洛谷的题目名称越来越瞎叉叉乱写了

原题传送门

思路


这道题看上去很高大上,但实际上一看(偷偷翻算法书)就知道这是某数列的通项公式(作为一个OIer,这是基本的数学素养,不懂者......退役吧)。

既然知道是斐波那契数列,那么,脱口而出:F(n)=F(n-1)+F(n-2),那么恭喜您,退役吧(这就是本蒟蒻的最初想法),为什么不行呢?大家构建一下递归树(栈)就知道了,递归层数本身会栈溢出不说,光是时间复杂度,和直接拿题目给的公式模拟的时间复杂度相当了,大约是O(nn),也就是说,您成功的吧O(n)的水题变成了NP完全问题,那么正解是什么呢?

其实注意一下题目的分类——递推,便可知道正解:F[n]=F[n-1]+F[n-2],看上去没什么区别对吗?那么恭喜您又可以退役了(非专业人士请走开),这样直接将时间降为线性,将空间也降为线性,但是,这是DP的思想,违背了题目的初衷(虽然已经能AC):递归,况且也不是最好的算法,所以——还需要优化。时间已降为线性,再要减也可以,但要用斐波那契堆,过于复杂,不展开了(不会),但空间可以降为O(1)——运用递推。

不多废话了,上代码(真正的程序员跟他讲解再多都没有直接上代码直观)。

Code


#include<iostream>
using namespace std;
long long a=1,b=1,c=0;///因为n<=48,所以大一点,用long long
int n,i;
int main()
{
    cin>>n;
    for (i=3;i<=n;i++)
    {
        c=a+b;
        a=b;
        b=c;
    }
    cout<<c<<".00";///".00"是为了符合题意.......
    return 0;
}

后记

等我学会斐波那契堆后再来继续优化吧,时间复杂度应该是可以降为O(log2n).

posted @ 2019-09-08 20:10  Kai02  阅读(273)  评论(0编辑  收藏  举报
Copyright © 2019-2020 拱大垲. All rights reserved.