【bzoj2796】 [Poi2012]Fibonacci Representation
2017-08-29 20:14
260 查看
Description
Fib数列0,1,1,2,3,5,8,13,21。
给出一个数字,用FIB数列各项加加减减来得到。例如
10=5+5
19=21-2
17=13+5-1
1070=987+89-5-1
Input
In the first line of the standard input a single positive integer is given (1 <=P<=10) that denotes the number of queries. The following lines hold a single positive integer K each 1<=K<=10^17.
Output
For each query your program should print on the standard output the minimum number of Fibonacci numbers needed to represent the number k as their sum or difference.
Sample Input
1
Sample Output
1070
题解
因为F[k]*2=F[k+1]+F[k-2],即存在最优解满足同一个FIB数出现次数不超过1
令l表示小等于n且最大的斐波那契数,r为其后一项,可以暴力或者二分求
dp(n) = min{ dp(n-l) , dp(r-n) } + 1
使用记忆化搜索
代码
Fib数列0,1,1,2,3,5,8,13,21。
给出一个数字,用FIB数列各项加加减减来得到。例如
10=5+5
19=21-2
17=13+5-1
1070=987+89-5-1
Input
In the first line of the standard input a single positive integer is given (1 <=P<=10) that denotes the number of queries. The following lines hold a single positive integer K each 1<=K<=10^17.
Output
For each query your program should print on the standard output the minimum number of Fibonacci numbers needed to represent the number k as their sum or difference.
Sample Input
1
Sample Output
1070
题解
因为F[k]*2=F[k+1]+F[k-2],即存在最优解满足同一个FIB数出现次数不超过1
令l表示小等于n且最大的斐波那契数,r为其后一项,可以暴力或者二分求
dp(n) = min{ dp(n-l) , dp(r-n) } + 1
使用记忆化搜索
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<set> #include<ctime> #include<vector> #include<cmath> #include<algorithm> #include<map> #define mod 1000000007 #define ll long long #define inf 2e18 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } map<ll,int>dp; ll n,f[105]; int num; int dfs(ll n) { if (dp ) return dp ; int l=1,r=num; while (l!=r) { int mid=(l+r+1)>>1; if (f[mid]<=n) l=mid;else r=mid-1; } if (f[l]==n) return 1; int ans=dfs(n-f[l]); if (f[l+1]) ans=min(ans,dfs(f[l+1]-n)); dp =ans+1; return dp ; } int main() { int Case=read(); f[1]=1;f[0]=1;num=1; for (int i=2;f[i-1]<=inf;i++,num++) f[i]=f[i-1]+f[i-2]; while (Case--) { scanf("%lld",&n); printf("%d\n",dfs(n)); } return 0; }
相关文章推荐
- 【bzoj2796】 [Poi2012]Fibonacci Representation
- BZOJ2796 [Poi2012]Fibonacci Representation
- BZOJ 2796: [Poi2012]Fibonacci Representation
- bzoj2796 [Poi2012]Fibonacci Representation 贪心
- BZOJ2796: [Poi2012]Fibonacci Representation
- [BZOJ2796][Poi2012]Fibonacci Representation
- bzoj 2796[Poi2012]Fibonacci Representation 贪心
- 【POI2012】【BZOJ2796】Fibonacci Representation
- [BZOJ 2796]POI2012 Fibonacci Representation
- bzoj 2796: [Poi2012]Fibonacci Representation 记忆化搜索
- 【BZOJ】【P2802】【POI2012】【Warehouse Store】【题解】【贪心】
- [BZOJ 2801]POI2012 Minimalist Security
- BZOJ 2802: [Poi2012]Warehouse Store
- bzoj 2789 [Poi2012]Letters 树状数组
- bzoj 3060[Poi2012]Tour de Byteotia 贪心+生成树
- [BZOJ2788][Poi2012]Festival(差分约束+floyed+tarjan)
- BZOJ2795: [Poi2012]A Horrible Poem
- BZOJ2793 [Poi2012]Vouchers 调和级数
- BZOJ 2794: [Poi2012]Cloakroom 询问离线 背包dp
- [BZOJ 2789]POI2012 Letters