moreD学FIB 解题报告
其中 \(N \leq 1e18\) , \(T \leq 1e3\)
注意到用于凑数的是斐波那契数列,所以可以用于凑数的数字不超过 \(logn\) 个。
直接搜索,常规剪枝即可
启示:充分剪枝的前提下,可以使用 STL 容器进行记忆化
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
inline int max(int x,int y){return x>y?x:y;}
const int N=105;
typedef long long ll;
typedef pair<ll,int> pii;
int n,T;
ll a[N],d[N],ans,p;
map<pii,int> f;
int dfs(int u){
if(p>d[u]) return 0;
if(p==0)
return 1;
if(f[make_pair(p,u)]) return f[make_pair(p,u)];
int res=0;
for(int i=u;i>=1;i--)
if(p-a[i]>=0)
p-=a[i],res+=dfs(i-1),p+=a[i];
return f[make_pair(p,u)]=res;
}
void slove(){
scanf("%lld",&p);
f.clear();
printf("%d\n",dfs(n));
}
int main()
{
freopen("fib.in","r",stdin);
freopen("fib.out","w",stdout);
a[1]=1,a[2]=2;
for(int i=3;i<=100;i++){
a[i]=a[i-1]+a[i-2];
if(a[i]>=1e18) {n=i;break;}
}
for(int i=1;i<=n;i++) d[i]=d[i-1]+a[i];
scanf("%d",&T);
while(T--) slove();
return 0;
}