1. 程式人生 > >遞迴求解整數劃分問題

遞迴求解整數劃分問題

定義一個數組dnum用來儲存一個劃分中的每個數,用show函式來對一次劃分進行一次輸出,運用遞迴的方法進行整數的劃分,遞迴的時時候考慮5種情況,分別是n<m,n=m,n>m>1, n>= 1>=m和 0=<n <=m <=1的情況。本程式沒有考慮負整數的情況,對於負整數的情況只需要增加一個判斷變數flag,flag=1時是負整數,此時稍微增加一下對應的輸出函式即可。

/* 
Subject:計算機演算法設計與分析 
Title:整數劃分問題:輸出一個整數的所有劃分並統計總劃分數 
Coder:learnordie
Date:Sept 11th,2014  
*/ 
 
/*
演算法思路:
定義一個數組dnum用來儲存一個劃分中的每個數,運用遞迴的方法進行整數的劃分
*/

#include<stdio.h>
#include<stdlib.h>
#include<math.h>

//show函式用於將dnum陣列中儲存的一個整數劃分輸出
//dnum中儲存的是一次整數劃分後的各個數,len為這次整數劃分好的各數的數目和
void show(int *dnum,int len){
	int i;
	printf("%d=",dnum[0]);
	if(len == 1) {
		printf("%d",dnum[1]);
	}
	else
	{	
		for(i=1;i<len-1;i++){
			printf("%d+",dnum[i]);
		}
	}
	printf("%d\n",dnum[len-1]);
	
}

//遞迴劃分整數,n為待劃分的整數,m為最大加數上限
int q(int n,int m,int *dnum,int len){
// n <= m <= 1 或 n<= 1 <= m 的情況
//當n>=1並且m=1時,q(n,m,result,length)=q(n-1,m,result,length)
//當n=0並且m=1時,輸出
//當n=1並且m>1時,輸出
	if(n>=0 && m==1){
		if(n==0){
			show(dnum,len);
		}
		else
		{
			dnum[len] = 1;
			q(n-1,m,dnum,len+1);
		}
		return 1;
	}
	else if(n==1 && m>1){
		dnum[len] = n;
		show(dnum,len+1);
		return 1;
	}
	//當n<m時候的情況
	else if(n<m){
		return q(n,n,dnum,len);
	}
	//當n=m時候的情況
	else if(n==m){
		dnum[len] = m;
		show(dnum,len+1);
		return q(n,m-1,dnum,len)+1;
	}
	//當n>m>1時候的情況
	else{
		dnum[len] = m;
		return   q(n-m,m,dnum,len+1) + q(n,m-1,dnum,len) ;
	}
}

void main(){
	int dnum[100]={0};
	int t,len;
	len = 1;
	printf("please enter the number:");
	scanf("%d",dnum);
	printf("the result is:\n");
	t=q(dnum[0],dnum[0],dnum,len);
	printf("the number is:%d\n",t);
	system("pause");
}



相關推薦

求解整數劃分問題

定義一個數組dnum用來儲存一個劃分中的每個數,用show函式來對一次劃分進行一次輸出,運用遞迴的方法進行整數的劃分,遞迴的時時候考慮5種情況,分別是n<m,n=m,n>m>1,

求解整數的分劃問題

整數劃分問題是演算法中的一個經典命題之一,有關這個問題的講述在講解到遞迴時基本都涉及到。     所謂整數劃分,是指把一個正整數n寫成如下形式:     n=m1+m2+m3+....+mi;

整數劃分的java程式設計實現

整數劃分:      正整數n表示成一系列正整數之和:      n=n1+n2+n3...+nk(其中,n1>=n2>=n3...>=nk>=1,k>=1),p(n)就

經典整數劃分問題

整數劃分問題是將一個正整數n拆成一組數連加並等於n的形式,且這組數中的最大加數不大於n。 比如6的整數劃分為    最大數(m)        6         6      5          

整數劃分問題(路徑輸出)【求解方式】

簡述 具體的函式可以參照 這個連結 程式碼 #include <iostream> using namespace std; #include <string> vo

輸入兩個整數n和m,從數列1,2,3,...,n中隨意取幾個數,使其和等於m,將其所有可能的組合列出來。 求解

/* *[email protected] 轉載請註明出處 *問題:輸入兩個整數n和m,從數列1,2,3,...,n中隨意取幾個數, *使其和等於m,將其所有可能的組合列出來。 *求解思路:(遞迴求解) *(1)如果n>m則數列中>m的部分不可能參與組

整數次冪的求解

整數次冪一般解法 時間複雜度O(n)的方法可以迭代n次,然後相乘結果返回,例如求xn虛擬碼: double pow(x,n) { res=x; while(n--)

[工作準備--演算法] 八皇后問題--求解

目標 在8*8的的國際象棋中擺上八個皇后 使其不能相互攻擊 問題分析 問題的解向量:(x0,x2,x3,….,x7) 採用陣列的下標i 表示皇后的所在行 採用陣列元素x[i]表示皇后的所在列向量 約束條件

求解單鏈表中的最大值

1 #include<iostream> 2 using namespace std; 3 4 typedef struct LNode { 5 int data; 6 LNode *next; 7 }Lnode, *LinkList; 8 9 bool

求解走臺階問題,一次可以走一步、兩步、三步、...、n步(經典面試題——增強版走臺階)

1、問題描述       現在有一個臺階,一共有n階,你一次性可以走1步、2步、3步、......、n步。問:一共有多少種走法。 2、求解思路       第一步走1階:那麼這種情況下的走法數量和剩下n-1階的走法數量有關;

Java:利用求解分桔子問題

問題描述:        日本著名數學遊戲專家中村義作教授提出這樣一個問題:父親將2520個桔子分給六個兒子。分完 後父親說:“老大將分給你的桔子的1/8給老二;老二拿到後連同原先的桔子分1/7給老三;老三拿到後連同原先的桔子分1/6給老四;老四拿到後連同

Java 通過求解漢諾塔問題 原始碼 經典問題講解

漢諾塔問題描述:有三根柱子 A、B、C ,在A從下向上按照從大到小的順序放著64個圓盤,以B為中介,把盤子全部移動到C上。移動過程中,要求任意盤子的下面要麼沒有盤子,要麼只能有比它大的盤子。 分析:為了將N個盤子從A移動到C,需要先把第N個盤子上面的N-1個盤子移動到B上,這樣才能將第

【劍指offer】斐波那契數列非求解第N項

public class Solution {    public int Fibonacci(int n) {       //錯誤輸入處理       if

漢諾塔問題求解(python)

漢諾塔問題遞迴求解(python) 漢諾塔(Hanoi)問題 古代有一個梵塔,塔內有三個座x,y,z壇,x座上有64個盤子,盤子大小不等,大的在下,小的在上。有一個和尚想把這64個盤子從x座移到z座,但每次只能允許移動一個盤子,並且在移動過程中,3個座上的盤子始終

演算法(Java筆記)—推&求解斐波拉契數列

遞推演算法——理性思維模式的代表,其原理是根據已有的資料和關係,逐步推導而得到結果。 演算法的執行過程: 根據已知結果和關係,求解中間結果。 判定是否達到要求,未達到則繼續重複第一步,直到尋找到正

演算法筆記之 全排列演算法 一 求解

集合R={1,2,3,4}的全排列 可以分解為:1,{2,3,4}的全排列 + 2,{1,3,4}的全排列 + 3,{1,2,4}的全排列 + 4,{1,2,3}的全排列。 繼續分解:{2,3,4} 為 2,{3,4}的全排列,3,{2,4},  4,{2,3}………………

合數的因式分解(求解,兩種方法)

#include <stdio.h> #include <math.h> //判斷一個數是不是素數 int isPrime(int n) {     if(n<2)return 0 ;else{int t = (int)sqrt(n);int

整數分解為若干項之和

輸入樣例: 7 輸出樣例: 7=1+1+1+1+1+1+1;7=1+1+1+1+1+2;7=1+1+1+1+3;7=1+1+1+2+2 7=1+1+1+4;7=1+1+2+3;7=1+