作者 任唯
单位 河北农业大学
给定一个自然数n,由n 开始可以依次产生半数集set(n)中的数如下(注意半数集是多重集)。
- n∈set(n);
- 在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;
- 按此规则进行处理,直到不能再添加自然数为止。
例如,set(6)={6,16,26,126,36,136}。半数集set(6)中有6 个元素。
输入格式:
一个自然数n(0<n<1000)
输出格式:
半数集set(n)中的元素个数
输入样例:
6
输出样例:
6
个人思路:
对于一个自然数n,要在他的左边加入一个小于他一半,我们有1到n/2种加入方法,而这次加入的数左边继续加入小于他一半的数,根据这个特性我们可以用记忆化搜索,对于计算过的半数集直接拿来用就可以。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
int f[N];
int ret(int n) {
if (f[n] > 0) return f[n]; //大于零代表已经计算过
int ans = 1;
for (int i = n / 2; i >= 1; i--) { //没有计算过的我们通过递归计算
ans += ret(i);
}
f[n] = ans; //更新f[n]的值
return ans;
}
int main()
{
int n;
cin >> n;
f[1] = 1;
cout << ret(n);
}
\