半數集問題描述:
給定一個自然數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; }
