# [NOIP2001 普及组] 数的计算
## 题目描述
给出正整数 n,要求按如下方式构造数列:
1. 只有一个数字 n 的数列是一个合法的数列。
2. 在一个合法的数列的末尾加入一个正整数,但是这个正整数不能超过该数列最后一项的一半,可以得到一个新的合法数列。
请你求出,一共有多少个合法的数列。两个合法数列 a, b 不同当且仅当两数列长度不同或存在一个正整数 i <= |a|,使得 a_i != b_i。
## 输入格式
输入只有一行一个整数,表示 n。
## 输出格式
输出一行一个整数,表示合法的数列个数。
### 样例输入 #1
6
### 样例输出 #1
6
## 提示
### 样例 1 解释
满足条件的数列为:
- 6
- 6, 1
- 6, 2
- 6, 3
- 6, 2, 1
- 6, 3, 1
### 数据规模与约定
对于全部的测试点,保证 1 <= n <= 1000。
分析:
本题可使用递归实现(OJ评测:100分)
#include<bits/stdc++.h>
using namespace std;
int a[1010];
int main(){
int n;
cin>>n;
a[1]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=i/2;j++)
a[i]+=a[j];
a[i]++;
}
cout<<a[n];
return 0;
}
但是还可以继续优化
判断一下奇偶,偶数位只需要增加 a [ i / 2 ] 即可
便得到以下代码(OJ测试:100分)
#include<bits/stdc++.h>
using namespace std;
int a[1010];
int main(){
int n;
cin>>n;
a[1]=1;
for(int i=2;i<=n;i++){
a[i]=a[i-1];
if(i%2==0)a[i]+=a[i/2];
}
cout<<a[n];
return 0;
}