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

  先定序地考虑一个菲波拉契数如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. Spring入门第十三课

    通过FactoryBean来配置Bean package logan.spring.study.factoryBean; public class Car { private String brand ...

  2. yzm10与战地信使 yzm10原创系列

    yzm10与战地信使 M国与R国正进行着激烈的鏖战,此时的yzm10从R国窃取了最高军事机密,这份情报将是此次战役的转折点,如果M国得到了这份情报,就能够取得这次战争的胜利.yzm10当然是站在M国这 ...

  3. Golang : cobra 包简介

    Cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序.同时,Cobra 也是一个应用程序,用来生成应用框架,从而开发以 Cobra 为基础的应用.本文的演示环境为 ubuntu 1 ...

  4. ue4 代码入门

    官网:暴露游戏元素给蓝图 https://docs.unrealengine.com/latest/CHN/Engine/Blueprints/TechnicalGuide/ExtendingBlue ...

  5. 剑指OFFER之打印1到最大的N位数(九度OJ1515)

    题目描述: 给定一个数字N,打印从1到最大的N位数. 输入: 每个输入文件仅包含一组测试样例.对于每个测试案例,输入一个数字N(1<=N<=5). 输出: 对应每个测试案例,依次打印从1到 ...

  6. 省选准备 MISTAKE 大全

    2019-03-29 [NOI2016]网格 如果是矩形,要记得考虑n或m=1的情况,不要潜意识里就以为矩形就是接近正方形的那种理想矩形. 写bool型的函数,return 的语句要想清楚,不要放错位 ...

  7. MyBatis入门Bug集锦X1

  8. A.DongDong破密码

    链接:https://ac.nowcoder.com/acm/contest/904/A 题意: DongDong是一个喜欢密码学的女孩子,她养的萨摩耶叼着一张带着加密信息的纸条交给了她,如果她不能破 ...

  9. GUI的最终选择 Tkinter(八):Message组件、Spinbox组件、PanedWindow组件、Toplevel组件

    Message组件 Message(消息)组件是Label组件的变体,用于显示多行文本消息,Message组件能够自动执行,并调整文本的尺寸使其适应给定的尺寸. from tkinter import ...

  10. 4. 把一幅彩色图像的R、G、B分量单独显示。

    #include <cv.h> #include <highgui.h> int main(void) { IplImage* oo = cvLoadImage(); IplI ...