题目大意:
第二关和很出名的斐波那契数列有关,地球上的OIer都知道:F1=1, F2=2, Fi = Fi-1 + Fi-2,每一项都可以称为斐波那契数。现在给一个正整数N,它可以写成一些斐波那契数的和的形式。如果我们要求不同的方案中不能有相同的斐波那契数,那么对一个N最多可以写出多少种方案呢?
做题思路:
这个题纯看的题解,,有点规律性的东西,num[i]=1+num[i-2],每两个斐波那契数,会增加一种表达方式,就可以对组成n的最原始的斐波那契数进行分解,dp[i][1]表示第i个斐波那契数选的种数,dp[i][0]表示第i个斐波那契数不选的情况数,从小到大dp就可以了
1
2
3 3=2+1
5 5=3+2
8 8=5+3=5+2+1
13 13=8+5=8+3+2
21 21=13+8=13+5+3=13+5+2+1
代码:
#include<bits/stdc++.h>
#define MAX 1000000000000000000
using namespace std;
long long f[100],N,dp[100][3],ans[100];
int main()
{
int s=2,i;
f[1]=1;f[2]=2;
while(f[s]<=MAX)
{
f[++s]=f[s-1]+f[s-2];
}
//f[++s]=0x3ffffffffff;
scanf("%lld",&N);
int k=1;
for(i=s;i>0,N>0;i--)
{
if(f[i]<=N) {ans[k++]=i;N-=f[i];}
}
dp[k-1][1]=1;dp[k-1][0]=(ans[k-1]-1)>>1;
for(i=k-2;i>=1;i--)
{
dp[i][1]=dp[i+1][1]+dp[i+1][0];
dp[i][0]=dp[i+1][1]*((ans[i]-ans[i+1]-1)>>1)+dp[i+1][0]*((ans[i]-ans[i+1])>>1);
//cout<<i<<" "<<ans[i]<<" "<<dp[i][0]<<" "<<dp[i][1]<<endl;
}
printf("%lld",(dp[1][1]+dp[1][0]));
}