zoukankan      html  css  js  c++  java
  • 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=1+2+13=1+2+5+8
    对于30%的数据,n<=256
    对于100%的数据,n<=10^18

    Solution


    有一个数学结论:第i个斐波那契数 拆成别的互不相同的斐波那契数表示,最多有(i-1)/2 种。那么我们用贪心,找出这个给出的数分解成斐波那契数的一个方案,再递推求解。

    Code


    //Writer : Hsz %WJMZBMR%tourist%hzwer
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #include<stack>
    #include<vector>
    #include<cstdlib>
    #include<algorithm>
    #define LL long long
    using namespace std;
    LL p[100],num;
    LL n,fi[100],cnt,ans;
    void fib(int x) {
    	if(fi[x-1]>n) {
    		cnt=x-1;
    		return;
    	}
    	fi[x]=fi[x-1]+fi[x-2];
    
    	fib(x+1);
    }
    LL f[105][2];//第i个fib,拆分/不拆 方案数。
    int main() {
    	cin>>n;
    	fi[0]=fi[1]=1;
    	fib(2);
    	for(int i=cnt; i; i--) {
    		if(n>=fi[i]) n-=fi[i],p[++num]=i;
    	}
    	sort(p+1,p+1+num);
    	f[1][1]=1;f[1][0]=(p[1]-1)/2;
    	for(int i=2; i<=num; i++) {
    		f[i][1]=f[i-1][1]+f[i-1][0];
    		f[i][0]=((p[i]-p[i-1]-1)/2)*f[i-1][1]+((p[i]-p[i-1])/2)*f[i-1][0];//整个表示不能有重复的数。
    	}
    	cout<<f[num][0]+f[num][1];
    	return 0;
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    最深叶节点的最近公共祖先
    ML-Agents(十)Crawler
    ML-Agents(九)Wall Jump
    ML-Agents(八)PushBlock
    ML-Agents(七)训练指令与训练配置文件
    Unity Editor扩展编辑器中显示脚本属性
    ML-Agents(六)Tennis
    数据结构(二)—栈
    ML-Agents(五)GridWorld
    ML-Agents(四)3DBall补充の引入泛化
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9135666.html
Copyright © 2011-2022 走看看