1. 程式人生 > 其它 >【計算機演算法】遞迴——半數集問題

【計算機演算法】遞迴——半數集問題

技術標籤:演算法

題目

問題描述:給定一個自然數n,由n開始可以依次產生半數集set(n)中的數如下:
(1) n∈set(n) ;
(2) 在n的左邊加上一個自然數,但該自然數不能超過最近新增的數的一半;
(3) 按此規則進行處理,知道不能再新增自然數為止。
例如,set(6)={6,16,26,126,36,136},半數集set(6)中有6個元素。
輸入:整數n(0<n<1000)
輸出:半數集set(n)中的元素個數。
請設計遞迴函式,求出set(n)的個數,並分析演算法時間複雜度,對演算法進行改進,用程式驗證遞迴演算法,以及改進之後的演算法。
1)設計遞迴函式、分析演算法時間複雜度

2)改進演算法

解答

1.程式碼如下

#include<iostream>
using namespace std;
#define N 1000
int bsj(int n){
    int sum = 1;//本身為1種
    if(n > 1)
    	for(int i = 1;i <= n / 2;i++)
        	sum += bsj(i);
    return sum;
}
int main(){
	int n;
	cin>>n;
	if(n > 1000) return 0;
	cout<<bsj(n)<<endl;
return 0; }

執行結果如下:
在這裡插入圖片描述
該演算法的時間複雜度應為O(n的n次方),存在有的數是重複的問題


2. 通過設定陣列來減少重複
#include<iostream>
using namespace std;
#define N 1000
int temp[500] = {0};
int bsj(int n){
    int i,sum = 1; //本身為1種
    
    //避免了重複加的問題 
    if(temp[n] > 0)
        temp[n] = sum;
    for(i = 1;i <= n / 2;i++)
       	sum +
= bsj(i); temp[n] = sum; return sum; } int main(){ int n; cin>>n; if(n > 1000) return 0; cout<<bsj(n)<<endl; return 0; }

執行結果如下:
在這裡插入圖片描述