CDOJ 1133 菲波拉契数制 变直接统计为构造

菲波拉契数制

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

Submit Status

我们定义如下数列为菲波拉契数列:

F(1)=1F(1)=1

F(2)=2F(2)=2

F(i)=F(i−1)+F(i−2)(i>=3)F(i)=F(i−1)+F(i−2)(i>=3)

给定任意一个数,我们可以把它表示成若干互不相同的菲波拉契数之和。比如1313有三种表示法

13=1313=13

13=5+813=5+8

13=2+3+813=2+3+8

现在给你一个数nn,请输出把它表示成若干互不相同的菲波拉契数之和有多少种表示法。

Input

第一样一个数TT,表示数据组数,之后TT行,每行一个数nn。

T≤105T≤105

1≤n≤1051≤n≤105

Output

输出TT行,每行一个数,即nn有多少种表示法。

Sample input and output

Sample Input Sample Output
6
1
2
3
4
5
13
1
1
2
1
2
3

Source

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
typedef  long long  ll;
typedef unsigned long long ull;
#define MM(a,b) memset(a,b,sizeof(a));
#define inf 0x7f7f7f7f
#define FOR(i,n) for(int i=1;i<=n;i++)
#define CT continue;
#define PF printf
#define SC scanf
const int mod=1000000007;
const int N=1e5+100;
int dp[N],a[N];

int main()
{
    MM(dp,0);
    a[1]=1;a[2]=2;
    int cnt=3;
    for(;a[cnt-1]<=1e5;cnt++)
         a[cnt]=a[cnt-1]+a[cnt-2];
    cnt-=2;

    dp[0]=1;
    for(int i=1;i<=cnt;i++)
        for(int j=100000;j>=a[i];j--)
         dp[j]+=dp[j-a[i]];
    int n,cas;
    scanf("%d",&cas);
     while(cas--)
     {
       scanf("%d",&n);
       printf("%d\n",dp[n]);
     }
    return 0;
}

  错因分析:这道题想到了直接统计,比如1有一种组成方式,2有一种,那么因为3=1+2,所以3=两种

5=2+3,所以5也有两种.....但是无法处理数字重复使用的情况,比如13=5+8,但是5=3+2,8=5+3

这样的话那么3很有可能被重复使用,但是数字又不能出现重复。。。所以就没办法了。。

所以统计走不通的话,就只有改成构造了,枚举一下斐波那契数能构造出来的数,细心可以发现斐波那契数大概也就20多个的样子(在<=1e5范围内)。

时间: 2024-08-05 19:04:06

CDOJ 1133 菲波拉契数制 变直接统计为构造的相关文章

UESTC_菲波拉契数制 2015 UESTC Training for Dynamic Programming&lt;Problem E&gt;

E - 菲波拉契数制 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 我们定义如下数列为菲波拉契数列: F(1)=1 F(2)=2 F(i)=F(i−1)+F(i−2)(i>=3) 给定任意一个数,我们可以把它表示成若干互不相同的菲波拉契数之和.比如13有三种表示法 13=13 13=5+8 13=2+3+8 现在给你一个数n,请输出把它表示成若干互

UESTC_菲波拉契数制升级版 2015 UESTC Training for Dynamic Programming&lt;Problem L&gt;

L - 菲波拉契数制升级版 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 我们定义如下数列为菲波拉契数列: F(1)=1 F(2)=2 F(i)=F(i−1)+F(i−2)(i>=3) 给定任意一个数,我们可以把它表示成若干互不相同的菲波拉契数之和.比如13有三种表示法 13=13 13=5+8 13=2+3+8 现在给你一个数n,请输出把它表示成

[dp][uestc][详细]L - 菲波拉契数制升级版

L - 菲波拉契数制升级版 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 我们定义如下数列为菲波拉契数列: F(1)=1 F(2)=2 F(i)=F(i−1)+F(i−2)(i>=3) 给定任意一个数,我们可以把它表示成若干互不相同的菲波拉契数之和.比如13有三种表示法 13=13 13=5+8 13=2+3+8 现在给你一个数n,请输出把它表示成

菲波拉契数列(传统兔子问题)

题目: 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 斐波那契数: 亦称之为斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.……在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=Fn-1+Fn-2(n>=2,n∈N*),用文字来说,就

C语言-郝斌笔记-005菲波拉契序列

菲波拉契序列 1 /* 2 菲波拉契序列 3 1 2 3 5 8 13 21 34 4 */ 5 6 # include <stdio.h> 7 8 int main(void) 9 { 10 int n; 11 int f1, f2, f3; 12 int i; 13 14 f1 = 1; 15 f2 = 2; 16 17 printf("请输入您需要求的想的序列: "); 18 scanf("%d", &n); 19 20 if (1 ==

菲波拉契数列

1 /* 2 * 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子, 3 * 假如兔子都不死,问每个月的兔子总数为多少? 4 //这是一个菲波拉契数列问题 5 6 */ 7 public class Test7 { 8 public static void main(String[] args) { 9 System.out.println("第1个月:" + 1); 10 System.out.println("第2个月:&

用递归求菲波拉契序列第N项的值

1 #include <stdio.h> 2 /* 3 题目:用递归求菲波拉契序列第N项的值 4 */ 5 int func(int n); 6 7 int main(void) 8 { 9 int N; 10 gogogo: printf("输入要求的项数(例:求第3项的值输入3)\n"); 11 scanf("%d",&N); 12 printf("第%d项的值 = %d\n",N,func(N)); 13 14 goto

7,菲波拉契数

题目一: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)n<=39 public int Fibonacci(int n) { if(n==0) return 0; if(n==1) return 1; return Fibonacci(n-1)+Fibonacci(n-2); } 题目二: 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). n个台阶:第一次跳一阶,还剩n-

求菲波拉契数列第n项的值

public int Solution(int n) { if(n < 3) { return 1; }else { int[] arr = new int[n]; arr[0] = 1; arr[1] = 1; for(int i = 3;i <= n;i++) { arr[i] = arr[i-1] + arr[i-2]; } return arr[n]; } }