[CF126D]Fibonacci Sums/[BJOI2012]最多的方案

[CF126D]Fibonacci Sums/[BJOI2012]最多的方案

题目大意:

将\(n(n\le10^9)\)表示成若干个不同斐波那契数之和的形式,求方案数。

思路:

如果不考虑\(0\),则\(10^9\)以内的斐波那契数只有86个。

首先求出字典序最大的方案,考虑分裂里面的数。

用\(c_i\)表示字典序最大方案在斐波那契数列中的下标(递增),\(f_{i,j}\)表示考虑到第\(i\)个数,本身是否分裂的方案数。

转移方程为:
\[
f_{i,0}=f_{i-1,0}+f_{i-1,1}\f_{i,1}=\lfloor\frac{c_i-c_{i-1}-1}2\rfloor f_{i-1,0}+\lfloor\frac{c_i-c_{i-1}}2\rfloor f_{i-1,1}
\]

单次询问时间复杂度\(\mathcal O(86)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<algorithm>
typedef long long int64;
inline int64 getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int64 x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
int64 f[87][2],c[87],fib[87]={
0,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578,5702887,9227465,14930352,24157817,39088169,63245986,102334155,165580141,267914296,433494437,701408733,1134903170,1836311903,2971215073ll,4807526976ll,7778742049ll,12586269025ll,20365011074ll,32951280099ll,53316291173ll,86267571272ll,139583862445ll,225851433717ll,365435296162ll,591286729879ll,956722026041ll,1548008755920ll,2504730781961ll,4052739537881ll,6557470319842ll,10610209857723ll,17167680177565ll,27777890035288ll,44945570212853ll,72723460248141ll,117669030460994ll,190392490709135ll,308061521170129ll,498454011879264ll,806515533049393ll,1304969544928657ll,2111485077978050ll,3416454622906707ll,5527939700884757ll,8944394323791464ll,14472334024676221ll,23416728348467685ll,37889062373143906ll,61305790721611591ll,99194853094755497ll,160500643816367088ll,259695496911122585ll,420196140727489673ll,679891637638612258ll
};
int main() {
    for(register int T=getint();T;T--) {
        int64 n=getint();
        int cnt=0;
        for(register int p=std::lower_bound(&fib[1],&fib[87],n)-fib;p;p--) {
            if(n>=fib[p]) {
                n-=fib[p];
                c[++cnt]=p;
            }
        }
        std::reverse(&c[1],&c[cnt]+1);
        f[1][0]=1;
        f[1][1]=(c[1]-1)/2;
        for(register int i=2;i<=cnt;i++) {
            f[i][0]=f[i-1][0]+f[i-1][1];
            f[i][1]=f[i-1][0]*((c[i]-c[i-1]-1)/2)+f[i-1][1]*((c[i]-c[i-1])/2);
        }
        printf("%lld\n",f[cnt][0]+f[cnt][1]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/skylee03/p/9366053.html

时间: 2024-11-29 02:40:35

[CF126D]Fibonacci Sums/[BJOI2012]最多的方案的相关文章

BJOI2012 最多的方案

Description ? 第二关和很出名的斐波那契数列有关,地球上的OIer都知道:F1=1, F2=2, Fi = Fi-1 + Fi-2,每一项都可以称为斐波那契数.现在给一个正整数N,它可以写成一些斐波那契数的和的形式.如果我们要求不同的方案中不能有相同的斐波那契数,那么对一个N最多可以写出多少种方案呢? Input ? 只有一个整数N. Output ? 一个方案数 Sample Input ? 16 Sample Output ? 4 HINT Hint:16=3+13=3+5+8=

[BJOI2012]最多的方案(记忆化搜索)

第二关和很出名的斐波那契数列有关,地球上的OIer都知道:F1=1, F2=2, Fi = Fi-1 + Fi-2,每一项都可以称为斐波那契数.现在给一个正整数N,它可以写成一些斐波那契数的和的形式.如果我们要求不同的方案中不能有相同的斐波那契数,那么对一个N最多可以写出多少种方案呢? 题意是说数列中不能出现相同的数. 显然要记忆化搜索. 直接搜会T,我们枚举下一个数填什么是要从大到小枚举,可以使效率有指数级的提升. 这是枚举上界,枚举下界可以用前缀和+二分来优化枚举复杂度. 加了这两个优化后代

Codeforces 126D Fibonacci Sums 求n由任意的Sum(fib)的方法数 dp

题目链接:点击打开链接 题意: 给定一个数n 问把这个数拆成多个不相同的fibonacci数 有多少种拆法 #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<set> #include<queue> #include<vector> #include<m

USACO 2.2 Subset Sums 【经典的方案DP+必要的转化】

题目在这里:https://www.luogu.org/problem/show?pid=1466#sub 1.把一个连续正整数集合平分,假设该正整数集合和为s,那么平分后的两个集合和均为s/2,因此我们首先把s是奇数的n排除掉 2.接着,我们发现:平分集合方案数======>用n个数凑s/2的方案数======>DP 3.若用f[i][j]表示用前i 个数凑j 的方案,则 f[i][j]=f[i-1][j]+f[i-1][j-i] (1<=i<=n,0<=j<=s/2

Codeforces Beta Round #93 (Div. 1 Only) D. Fibonacci Sums

先考虑一个斐波那契数能分成其他斐波那契数的方案,假如f[i]表示第i个斐波那契数,那么只要对他进行拆分,f[i-1]这个数字必定会存在.知道这一点就可以进行递推了.先将数字分成最少项的斐波那契数之和,s[i]表示第i项的数字对应的斐波那契数编号,F[i]表示对不第i项进行拆分,G[i]表示对第i项进行拆分,g[i]表示对编号为i的斐波那契数拆分的话,有多少种方案.那么可以得到递推式: F[i]=F[i-1]+G[i-1]; G[i]=F[i-1]*(g[s[i]-s[i-1]])+G[i-1]*

bzoj 2660: [Beijing wc2012]最多的方案【dp】

有点神奇的dp 首先注意到任意一个数都能被表示成若干个斐波那契数的和的形式 先求出n可以字典序最大的表示 设f[i][0/1]表示第i个斐波那契数选或者不选 如果当前数不选,那就选比他小的两个数,否则,需要不选比他小的两个数(连续的影响) #include<iostream> #include<cstdio> using namespace std; const int N=105; long long n,a[N],s[N],top,f[N][2]; int main() { s

【JavaScript】新浪微博ajax请求后改变地址栏url,但页面不跳转的方案解析

新浪微博当你弹出一个视频的时候再点下一页时,原视频还在,而且地址栏的url的页数变了.对于这种网上讨论最多的方案有以下几种: 一.通过锚点Hash实现在这方面其实国内很早就有做了,比如淘宝画报,通过的是在地址栏后面加#锚点实现的,浏览器是可以识别锚点为单位的历史记录的.但不 是说页面本身有这个锚点,锚点的Hash只是起到一个引导浏览器将这次的记录推入历史记录栈顶的作用. 二.通过HTML5加强型的History对象实现(类Pjax)可以通过window.history.pushState这个方法

工业防火墙架构与技术【第二节:硬件架构②】

2).满足对数据包的处理性能的高速度要求 任何防火墙的基本技术功能都是过滤报文.防火墙检查其接收的每个数据包,以确定数据包是否对应于流量模式的所需模板.防火墙然后过滤(丢弃)或转发与这些模板匹配的数据包.这些模板以规则的形式进行建模.在工控防火墙中,有针对已知协议提前建模好的规则模板,也有后期自动学习进行建模的规则模板.由于工控防火墙处理数据包是一个一个处理,包括数据包的校验,数据包每一层包头的处理,所以数据包越小,到达时间就越短,服务器处理数据包要求就越高.比如64B的小包,如果处理数据包要达

84. 从视图索引说Notes数据库(下)

作用和代价上文介绍了关系型数据库里的索引.Notes数据库里的索引隐藏在视图概念里(本文的讨论只针对Notes的视图索引,不包含全文索引.).开发人员创建的视图仅仅是存放在数据库里的一条设计文档,数据库引擎会依据它创建和更新索引.关系型数据库里的索引是从记录中抽取的数据排序而组成的数据结构(主要是B树),Notes视图的索引还包括未排序的列.计算值.分类.总计等等数据(数据结构仍然是B树,如果运气足够好的话,你会遇到Notes报出B-tree structure is invalid的错误).用