半数集问题描述:
给定一个自然数n,由n 开始可以依次产生半数集set(n)中的数如下。
(1) n∈set(n);
(2) 在n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;
(3) 按此规则进行处理,直到不能再添加自然数为止。
例如,set(6)={6,16,26,126,36,136}。半数集set(6)中有6 个元素。
注意半数集是多重集。
1、递归——效率低
1 //半数集问题 2 #include<iostream> 3 #include<cstdio> 4 #include<cstdlib> 5 using namespace std; 6 7 int comb(int n){ 8 int ans = 1; 9 if( n > 1 ) 10 for( int i = 1; i <= n/2; i++ ) 11 ans += comb(i); 12 return ans; 13 } 14 15 int main(){ 16 int n; 17 while( scanf("%d",&n) != EOF ){ 18 cout<<comb(n)<<endl; 19 } 20 return 0; 21 }
2、半数集问题递归算法——记忆式搜索
//半数集问题递归算法——记忆式搜索 #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std; int a[1001]; int comb(int n){ int ans = 1; if( a[n] > 0 ) return a[n]; for( int i = 1; i <= n/2; i++ ) ans += comb(i); a[n] = ans; return ans; } int main(){ int n; while( scanf("%d",&n) != EOF ){ memset(a,0,sizeof(a)); a[1] = 1; cout<<comb(n)<<endl; } return 0; }