[NOIP2001 普及组] 数的计算
题目描述
给出正整数 $n$,要求按如下方式构造数列:
- 只有一个数字 $n$ 的数列是一个合法的数列。
- 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
请你求出,一共有多少个合法的数列。两个合法数列 $a, b$ 不同当且仅当两数列长度不同或存在一个正整数 $i \leq |a|$,使得 $a_i \neq b_i$。
输入格式
输入只有一行一个整数,表示 $n$。
输出格式
输出一行一个整数,表示合法的数列个数。
样例 #1
样例输入 #1
6
样例输出 #1
6
提示
样例 1 解释
满足条件的数列为:
- $6$
- $6, 1$
- $6, 2$
- $6, 3$
- $6, 2, 1$
- $6, 3, 1$
数据规模与约定
对于全部的测试点,保证 $1 \leq n \leq 10^3$。
题解:
思路一:递推
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int f[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
f[i] = 1;
for (int j = 1; j <= i / 2; j++)
{
f[i] += f[j];
}
}
cout << f[n];
return 0;
}
思路二:递归(记忆化)
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int num[N];
int fun(int x)
{
if (x == 1) return 1;
int res = 1;
if (num[x]) return num[x];
for (int i = 1; i <= x / 2; i++)
{
res += fun(i);
}
num[x] = res;
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
cout << fun(n);
return 0;
}