题目描述

给出一个正整数x,问x最少能由多少个Fibonacci数加减算出。
例如1070=987+89-5-1,因此x=1070时答案是4。

输入

第一行一个正整数q (q<=10),表示有q组输出。
下面q行每行一个正整数x (x<=4*10^17)。

输出

输出q行,依次表示每个输出的答案。

样例输入

1
1070

样例输出

4
 
  因为f[i]=f[i-1]+f[i-2],f[i+1]=f[i]+f[i-1],能得到2f[i]=f[i+1]+f[i-2],所以最优答案一定存在没有一个FIB数被选两次的情况。预处理出FIB数,每一次二分找到最大的小于等于x的FIB数和最小的大于等于x的FIB数,然后求出差的绝对值,递归绝对值小的。至于为什么每次都取最接近x的,这样可以使递归要找的数更小,使答案更优。为什么每次要选最接近x的数?因为我们知道FIB数每一项等于前两项之和,如果每一次不选最大的,因为每一次选的都是越来越小的,那么要想加和等于能选的最大的,就要更多次数。
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
long long f[600];
long long cnt=1;
int t;
long long x;
long long findL(long long x)
{
int l=1;
int r=cnt;
int ans=1;
while(l<=r)
{
if(f[mid]<=x)
{
ans=mid;
l=mid+1;
}
else
{
r=mid-1;
}
}
return f[ans];
}
long long findR(long long x)
{
int l=1;
int r=cnt;
int ans=1;
while(l<=r)
{
if(f[mid]>=x)
{
ans=mid;
r=mid-1;
}
else
{
l=mid+1;
}
}
return f[ans];
}
int find(long long x)
{
long long l=findL(x);
long long r=findR(x);
if(l==r)
{
return 1;
}
if(x-l<=r-x)
{
return find(x-l)+1;
}
else
{
return find(r-x)+1;
}
}
int main()
{
f[0]=f[1]=1;
while(f[cnt-1]<=4e17)
{
f[++cnt]=f[cnt-1]+f[cnt-2];
}
scanf("%d",&t);
while(t--)
{
scanf("%lld",&x);
printf("%d\n",find(x));
}
}

BZOJ2796[Poi2012]Fibonacci Representation——贪心+二分查找的更多相关文章

  1. [BZOJ2796][Poi2012]Fibonacci Representation

    由于是斐波那契数列,所以$x_i+x_j<=x_k,i<j<k$ 所以猜测可以贪心选择两边近的数处理. #include<cstdio> #include<algo ...

  2. 贪心/二分查找 BestCoder Round #43 1002 pog loves szh II

    题目传送门 /* 贪心/二分查找:首先对ai%=p,然后sort,这样的话就有序能使用二分查找.贪心的思想是每次找到一个aj使得和为p-1(如果有的话) 当然有可能两个数和超过p,那么an的值最优,每 ...

  3. Codeforces Round #768 (Div. 2) D. Range and Partition // 思维 + 贪心 + 二分查找

    The link to problem:Problem - D - Codeforces   D. Range and Partition  time limit per test: 2 second ...

  4. 【bzoj2796】 [Poi2012]Fibonacci Representation

    给出一个数字,用FIB数列各项加加减减来得到. 问最少要多少个(可以重复使用) 大概试了一下,fibonacci数列的增长是很快的,大概到了90+项就超过了题目范围…… 所以每次找一个最近的fibon ...

  5. hdu 4190 Distributing Ballot Boxes(贪心+二分查找)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4190 Distributing Ballot Boxes Time Limit: 20000/1000 ...

  6. bzoj 2796: [Poi2012]Fibonacci Representation

    结论貌似是,,,肯定只有没有重复的数字.http://hzwer.com/6426.html 一开始猜的是贪心,感觉也是可以的啊...(想想都有道理,然而看到是神奇的(dp类)记忆化搜索,直接虚的不敢 ...

  7. BZOJ [Poi2012]Fibonacci Representation

    找最近的数 记忆化 (我也不知道为什么对的) #include<cstdio> #include<algorithm> #include<map> using na ...

  8. [POI2012]ROZ-Fibonacci Representation (贪心)

    大意: 给定数$n$, 求将$n$划分为最少的斐波那契数的和或差. 每次取相邻$n$的斐波那契数一定最优, 考虑证明. 结论1:存在一个最优解,使得每个斐波那契数使用不超过1次.(考虑$2F_n=F_ ...

  9. 抄书(B - 二分查找)

    抄书  (二分查找+贪心) 提示:二分查找一般写成非递归形式 时间复杂度:O(logn) 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action? ...

随机推荐

  1. java 学习------JDK1.8安装与配置

    1.下在JDK 1.8 2.解压安装 (一般选择默认路径安装) 3.配置环境变量     (我的电脑是windows10 系统) (1)计算机→属性→高级系统设置→高级→环境变量 (2)添加 JAVA ...

  2. 9-(基础入门篇)云端安装MQTT服务器

    https://www.cnblogs.com/yangfengwu/p/9953703.html 记得把文件拷贝到上一节配置的和云端共享的那个盘里面,好拷贝文件到云服务器 进入到bin目录 咱先以控 ...

  3. 使用awk按照行数切割文件

    最近在做一个事情,需要将一个文本文件按照行数进行切割,然后用了,awk的方法,感觉很好用, 记录一下. 脚本如下: #!/bin/bash ## 文件效果: 根据行数来切割文件 ## 参数1为要切割的 ...

  4. ASP.NET Core 登录失败。该登录名来自不受信任的域,不能与集成身份验证一起使用。

    原文:ASP.NET Core 登录失败.该登录名来自不受信任的域,不能与集成身份验证一起使用. 当进行数据迁移的时候提示 修改appsettings配置连接串的Trusted_Connection ...

  5. sql储存过程in(多个参数)

    一.用sql函数 首先要创建一个截取字符串的函数,新建一个查询,把下面代码复制进去执行. 函数SqlitIn的第一个参数是储存过程要in的字符串,第二个参数是分隔符 CREATE function S ...

  6. Python3.x:Selenium+PhantomJS爬取带Ajax、Js的网页及获取JS返回值

    前言 现在很多网站的都大量使用JavaScript,或者使用了Ajax技术.这样在网页加载完成后,url虽然不改变但是网页的DOM元素内容却可以动态的变化.如果处理这种网页是还用requests库或者 ...

  7. .NET CORE下的Cache

    .NET CORE 下的缓存跟之前ASP.NET下的缓存有所不同,应用.NET CORE缓存首先需要引入Microsoft.Extensions.Caching.Memory程序包 下面简单写了一个C ...

  8. NIO之缓冲区

    NIO引入了三个概念: Buffer 缓冲区 Channel 通道 selector 选择器 1.java.io优化建议 操作系统与Java基于流的I/O模型有些不匹配.操作系统要移动的是大块数据(缓 ...

  9. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及几种abp封装的Javascript函数库

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期         简介 经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这 ...

  10. awk技巧(如取某一行数据中的倒数第N列等)

    使用awk取某一行数据中的倒数第N列:$(NF-(n-1))比如取/etc/passwd文件中的第2列.倒数第1.倒数第2.倒数第4列(以冒号为分隔符) [root@ipsan-node06 ~]# ...