洛谷刷题日记.4

47 阅读2分钟

P1028 [NOIP 2001 普及组] 数的计算

题目描述

给出正整数 nn,要求按如下方式构造数列:

  1. 只有一个数 nn 的数列是一个合法的数列。
  2. 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。

请你求出,一共有多少个合法的数列。两个合法数列 a,ba, b 不同当且仅当两数列长度不同或存在一个正整数 iai \leq |a|,使得 aibia_i \neq b_i

输入格式

输入只有一行一个整数,表示 nn

输出格式

输出一行一个整数,表示合法的数列个数。

输入输出样例 #1

输入 #1

6

输出 #1

6

说明/提示

样例 1 解释

满足条件的数列为:

  • 66

  • 6,16, 1

  • 6,26, 2

  • 6,36, 3

  • 6,2,16, 2, 1

  • 6,3,16, 3, 1

    我们假设数字n能弄出来F(n)个合法数列 而这其中所拥有的合法数列又是由F(n/2)+F(n/2-1)+...一直到F(1)为止的 所以我们的思路就是将F(1)到F(n/2)的值全部加起来 然后再加1 "n本身也是合法数列",这样我们就得到了F(n)所能构造的合法数列 那么现在我们就可以编写我们的代码了

    int main(){
    int n;
    scanf("%d",&n);
    int F[n+1];//设为n+1方便我们去一一对应
    for(int i=1;i<=n;i++){
     F[i]=1;//把每个都初始化为1 确保他本身一个数字的时候是被计算的
    }
    F[1]=1;
    F[2]=2;
    F[2]=2;//题目给出
    for(int i=3;i<=n;i++){
      for(int u=1;u<=i/2;u++){
      F[i]+=F[u];//第一层循环是为了让我们计算并保留下<=n的数的合法数列 这样我们后续的求和就有用
      //而第二层函数则是求出对应的那个n的合法数列
      }
    }
    printf("%d",F[n]);//最后再输出F[n]即可
    return 0;
    }