数据很大,以背包的思路数组开不下。

  先定序地考虑一个菲波拉契数如fib(i)的表示法,假设i比较大,由菲波拉契数的定义可知道fib(i)=fib(i-1)+fib(i-2);要找到其它表示就继续拆分fib(i-1)或fib(i-2),假如拆分fib(i-1)得到fib(i)=2*fib(i-2)+fib(i-3),这不能保证保证互不相同的性质(补充,也许有人会考虑将这个式作为中间过程通过拆出矛盾项来保证唯一性,然而消除了一个矛盾必然产生新的矛盾,所以不行,具体地说将fib(i-2)=fib(i-3)+fib(i-4)消除了fib(i-2)的矛盾然而产生了fib(i-3)的矛盾,fib(i-3)又是由fib(i-1)得来,无法通过有限次拆分将矛盾消除),因此考虑拆fib(i-2),又得到一种表达方式fib(i)=fib(i-1)+fib(i-3)+fib(i-4);继续拆分,和前面类似,只能拆fib(i-4);不难发现每次只能拆最小的fib数,终点为fib(1)或fib(2);由上面过程可以得出:1或2+2*m=i,m是除了fib(i)本身以外其他的表示方法,上式可以得出m=(i-1)/2(/都表示向下取整,下同)。
  ok,我们成功地解决了n为菲波拉契数的情况;下面考虑n为菲波拉契数的组合的情况;假设n=fib(i)+fib(j),i>j;我们知道fib(i)和fib(j)单独的情况,现在组合起来可以借鉴刚刚拆分的思想,不同的是现在可能fib(i)和fib(j)都可以拆分;假设拆分fib(j)(可能你要问,为什么要拆小的那个?原因是在fib(i)拆分中会有和fib(j)拆分冲突的情况)得到(j-1)/2+1组;现在考虑拆fib(i),和一开始一样的思想只是终点发生了变化,为确定终点(保证独立性),我们考察fib(j)的拆分情况,我们发现在(j-1)/2种拆分中都是以fib(j-1)开头的,因此终点为fib(j)或fib(j+1),可以得到等式2*m1+j或(j+1)=i,m1=(i-j)/2,m1是除了fib(i)本身以外其他的表示方法;以fib(j)开头,即fib(j)本身,终点为fib(j+1)或fib(j+2),m2=(i-j-1)/2,m2是除了fib(i)本身以外其他的表示方法。综上,含fib(i)的表示有(j-1)/2+1种,不含fib(i)的表示有m1*(j-1)/2+m2。现在推广到n=fib(i)+fib(j)+fib(k),i>j>k的情况fib(j)和fib(k)的组合已经知道了,而且分两组以fib(j)开头的和以fib(j-1)开头的,对fib(i)拆分和上一种办法一样,由此给出dp[i][0]的定义:以fib(i-1)开头的所有组合,dp[i][1]:以fib(i)开头的所有组合。于是有状态转移方程dp[i][1]=dp[j][0]+dp[j][1],dp[i][0]=(i-j-1)/2*dp[j][1]+(i-j)/2*dp[j][0],最终结果为dp[maxi][0]+dp[maxi][1]。

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std; long long int dp[][];//dp[i][0] 表示comb[0~i]的所有组合的降序排列中以fib[i-1]开头的 [1]表示以fib[i]开头的
long long int fib[]; void get_fibs()
{
fib[]=;fib[]=;
for(int i=;i<;i++)
fib[i]=fib[i-]+fib[i-];
}
vector<int> comb;//组成n的fib的下标
long long int n;
void solve()
{
comb.clear();
for(int i=;i>&&n;i--)
if(n>=fib[i])
{
n-=fib[i];
comb.push_back(i-);
}
sort(comb.begin(),comb.end());
dp[][]=;
dp[][]=comb[]/;
for(int i=;i<comb.size();i++)
{
dp[i][]=dp[i-][]+dp[i-][];
dp[i][]=(comb[i]-comb[i-]-)/*dp[i-][]+(comb[i]-comb[i-])/*dp[i-][];
}
printf("%lld\n",dp[comb.size()-][]+dp[comb.size()-][]);
} int main()
{
get_fibs();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
solve();
}
return ;
}

[dp][uestc]L - 菲波拉契数制升级版的更多相关文章

  1. UESTC_菲波拉契数制升级版 2015 UESTC Training for Dynamic Programming<Problem L>

    L - 菲波拉契数制升级版 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Su ...

  2. UESTC 2015dp专题 E 菲波拉契数制 dp

    菲波拉契数制 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/65 Descr ...

  3. [dp]uestc oj E - 菲波拉契数制

    E - 菲波拉契数制 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  4. Contest20140906 ProblemC 菲波拉契数制 DP

    C.菲波拉契数制时间:2s   内存:65536KB我们定义如下数列为菲波拉契数列:                    F (1) = 1                    F (2) = 2 ...

  5. UESTC_菲波拉契数制 2015 UESTC Training for Dynamic Programming<Problem E>

    E - 菲波拉契数制 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  6. CDOJ 1133 菲波拉契数制 变直接统计为构造

    菲波拉契数制 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit St ...

  7. 递归函数练习:输出菲波拉契(Fibonacci)数列的前N项数据

    /*====================================================================== 著名的菲波拉契(Fibonacci)数列,其第一项为0 ...

  8. e8_4输出菲波拉契数列的前10项

    program fbnq;{输出菲波拉契数列的前10项} var a:..] of integer; i:integer; begin a[]:=; a[]:=; do a[i]:=a[i-]+a[i ...

  9. C语言-郝斌笔记-005菲波拉契序列

    菲波拉契序列 /* 菲波拉契序列 1 2 3 5 8 13 21 34 */ # include <stdio.h> int main(void) { int n; int f1, f2, ...

随机推荐

  1. 牛客多校2 D-money(dp记录/贪心)

    D-money 链接:https://www.nowcoder.com/acm/contest/140/D来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K, ...

  2. HDU - 1150 POJ - 1325 Machine Schedule 匈牙利算法(最小点覆盖)

    Machine Schedule As we all know, machine scheduling is a very classical problem in computer science ...

  3. 如何升级一个JavaWeb应用

    准备db变更 准备整个war包或变更的文件 上传文件至云盘​(通常直接上传文件较慢,建议先传到云盘,然后下载) 从云盘下载 执行db变更 解压war到指定目录或替换变更的文件 修改设计IP地址的配置文 ...

  4. lightoj1009【DFS】

    思路: 连通快+二分图,每次+二分图大的元素个数. #include<bits/stdc++.h> using namespace std; typedef unsigned long l ...

  5. Android Studio如何导出可供Unity使用的aar插件详解

    http://www.cnblogs.com/xtqqkss/p/6387271.html 前言 项目之前使用Eclipse导出的jar文件来做与Android交互,最近因为工作需要需使用Androi ...

  6. 2017-9-22 NOIP模拟赛[xxy][数论]

    XXY 的 的 NOIP 模拟赛 4 4 —— 数学专场 A Description定义 f(x)表示 x 的约数和,例:f(12)=1+2+3+4+6+12=28给出 x,y,求Σf(i),i∈[x ...

  7. 洛谷P1014 Cantor表

    P1014 Cantor表 题目描述 现代数学的著名证明之一是Georg Cantor证明了有理数是可枚举的.他是用下面这一张表来证明这一命题的: 1/1 1/2 1/3 1/4 1/5 … 2/1 ...

  8. uoj#279. 【UTR #2】题目交流通道(容斥+数数)

    传送门 先考虑无解的情况,为以下几种:\(dis_{i,j}+dis_{j,k}<dis_{i,k}\),\(dis_{i,i}\neq 0\),\(dis_{i,j}\neq dis_{j,i ...

  9. 长春理工大学第十四届程序设计竞赛(重现赛)F.Successione di Fixoracci

    链接:https://ac.nowcoder.com/acm/contest/912/F 题意: 动态规划(Dynamic programming,简称dp)是一种通过把原问题分解为相对简单的子问题的 ...

  10. net core 中间件管道

    net core 中间件管道 .net core 管道(Pipeline)是什么? 由上图可以看出,.net core 管道是请求抵达服务器到响应结果返回的中间的一系列的处理过程,如果我们简化一下成下 ...