cdoj 斐波那契进制

//昨天在姜神的提醒下发现这种方法可以解决升级版的 非升级版直接01背包就好

//这题脑洞开得真是够大

解:大概要先把数分解成斐波拉契进制,x=f1*(0或1)+f2*(0或1)+...+fn*(0或1) f1表示第一个斐波拉契数字(和二进制分解很像 但是这里要分解成斐波拉契进制)

然后如果一个数分解后某三位位上为100 那么可以将其拆分为011(再拆01011 0101011)

于是有dp[i][0]代表某一位不拆 dp[i][1]代表某一位拆a[i]代表第i个1后面有多少0,于是

dp[i][0] += dp[i - 1][0] + dp[i - 1][1];
dp[i][1] += dp[i - 1][0] * (a[i] / 2) + dp[i - 1][1] * ((a[i] + 1) / 2);

//那个a[i]/2自己画出来看看就知道了 很显然的

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<queue>
 8 #include<vector>
 9 #include<map>
10 #include<stack>
11 #include<string>
12 
13 using namespace std;
14 
15 long long T;
16 long long f[100];
17 long long dp[100][2];
18 long long a[100];
19 long long cnt;
20 
21 void get_a(long long x){
22     long long e[100];
23     memset(e,0,sizeof(e));
24     for (long long i=90;i>=1;i--){
25             if (x>=f[i]){
26                     e[i]=1;
27                     x-=f[i];
28             }
29     }
30     long long tmp=0;
31     cnt=0;
32     memset(a,0,sizeof(a));
33     for (long long i=1;i<=90;i++){
34             if (e[i]==1){
35                     a[++cnt]=tmp;
36                     tmp=0;
37             }
38             else{
39                     tmp++;
40             }
41     }
42 }
43 
44 
45 int main(){
46     f[0]=1;
47     f[1]=1;
48     for (long long i=2;i<=90;i++) f[i]=f[i-1]+f[i-2];
49     scanf("%lld",&T);
50     for (long long cas=0;cas<T;cas++){
51             long long x;
52             scanf("%lld",&x);
53             get_a(x);
54             memset(dp,0,sizeof(dp));
55             dp[1][0]=1;
56             dp[1][1]=a[1]/2;
57             for (long long  i=2;i<=cnt;i++){
58                     dp[i][0]=dp[i-1][0]+dp[i-1][1];
59                     dp[i][1]=dp[i-1][0]*(a[i]/2)+dp[i-1][1]*((a[i]+1)/2);
60             }
61             printf("%lld
",dp[cnt][0]+dp[cnt][1]);
62     }
63     return 0;
64 }
65 /*
66 6
67 1
68 2
69 3
70 4
71 5
72 13
73 */
原文地址:https://www.cnblogs.com/baby-mouse/p/4502233.html