HDU 5167Fibonacci

来源:互联网 发布:手机淘宝如何卖二手货 编辑:程序博客网 时间:2024/06/07 02:52

题意:给一个数n,问这个数n(<=10^9)是否能表示为斐波那契数列中的数的乘积。

思路:先预处理得到斐波那契数列,先判断了一下,n<=10^9,该范围大概有40来个数,先预处理保存这些数即可。
接下来就进行DFS,但是每次枚举的范围都不变的话会超时的,因此需要每次缩小枚举的范围,这也是本题关键的一个剪枝技巧。
每次枚举的时候都从最大的斐波那契数开始,倒着进行枚举,这样下一次出现的斐波那契数一定比上一次的小,从而缩小了枚举范围。

下面贴代码,关键要注意DFS中的for循环:

#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <ctime>#include <ctype.h>#include <iostream>#include <map>#include <queue>#include <set>#define eps 1e-8#define INF 0x7fffffff#define PI acos(-1.0)#define seed 31//131,1313typedef long long LL;typedef unsigned long long ULL;using namespace std;LL f[50];void init() {    f[0] = 0;    f[1] = 1;    for(int i = 2; i <= 45; i++) {        f[i] = f[i-1] + f[i-2];    }}bool dfs(LL n, int x) {    if(n <= 3) {        return true;    }    for(int i = x; i >=3; i--) {         if(n % f[i] == 0) {            if(dfs(n / f[i], i)) {                return true;            }        }    }    return false;}int main() {    init();    int T;    LL n;    scanf("%d",&T);    while(T--) {        scanf("%I64d",&n);        if(dfs(n, 45)) {            printf("Yes\n");        }else {            printf("No\n");        }    }    return 0;}
0 0