问题描述:给定一个自然数n,由n开始产生半数集set(n)
(1)n属于set(n);
(2)在n的左边加上一个自然数,但该自然数不超过最近添加的数的一半;
(3)按此规则进行处理,直到不能再添加自然数为止。
例如:set(6)= {6,16,26,36,126,136}.。
输入:给出整数n
输出:set(n)的个数
分析:
可较容易得出递推关系:f(n) = 1+
由此可得出递归算法:
int comp(int n)
{
int ans = 1;
if(n > 1)
for(int i = 1;i<n/2;i++)
ans += comp(i);
return ans;
}
但传统的递归问题求解会有大量的重复子问题的无意义计算,所以可以改进此算法,设置一记录数组,记录已经求解的问题。
改进后的算法:
int a[1000]
int comp(int n)
{
int ans = 1;
if(a[n]>0) return a[n];
for(int i = 1;i<=n/2;i++)
{
ans += comp(i);
}
a[n] = ans;
return ans;
}
下面附可运行代码,入门小白调bug不易,如若复制请点赞
#include<iostream>
using namespace std;
int a[1000];
int comp(int n);
int main()
{
int n;
cin>>n;
cout<<comp(n)<<endl;
system("pause");
}
int comp(int n)
{
int ans = 1;
//说明已在之前求解过
if (a[n] > 0)
{
return a[n];
}
for (int i = 1; i <= n/2; i++)
{
ans += comp(i);
}
//存储结果
a[n] = ans;
return ans;
}