题意:
fi[0]=0,fi[1]=1
fi[i]=fi[i-1]+fi[i-2] i>1
给出一个数n,问这个数能不能有fi[]相乘得来。
限制:
0 <= n <= 1e9
思路:
直接枚举会超时,所以需要剪枝。
一个数的因子只可能比这个树小,所以需要在dfs的过程中不断缩小fi的查找区间,即查找小于等于当前这个数能被整除的区间。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;
typedef long long ll;
ll f[50];
inline 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 = 3; i <= x; 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("%lld",&n);
if(dfs(n, 45)) {
printf("Yes\n");
}else {
printf("No\n");
}
}
return 0;
}