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

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

這道題的思路參考0-1揹包:定義函式F(n,m)來求解這個問題,那麼F(n,m)可以分解為兩個子問題F(n-1,m)和F(n-1,m-n).由於題目要求列出所有的組合,使用類似動態規劃的方法比較複雜,我在這裡直接使用遞迴來解決這個問題。雖然效率可能不是很好,但是程式碼的可讀性還是比較好的。

#include <iostream>
#include<malloc.h>
#include<string.h>
 using namespace std;
 int length;
 void PrintSolutions(int *flag)
  {
  for (int i=0; i<length; i++)
   {
        if (flag[i] == 1)
         {
            cout << i+1 << "  ";
         }
     }
    cout << endl;
}
 void BagProblem(int m, int n, int *flag)
 {
     if(n<1 || m<1)
        return;
    if(m < n)
        n = m;
     if (n == m)
     {
        flag[n-1] = 1;
        PrintSolutions(flag);
        flag[n-1] = 0;
     }
    flag[n-1] = 1;
    BagProblem(m-n, n-1, flag);
    flag[n-1] = 0;
    BagProblem(m, n-1, flag);
 }

int main()
 {
    int m, n;
    cin >> m >> n;
    length = n;
    int *flag = (int *)malloc(sizeof(int)*n);
    memset(flag, 0, sizeof(flag));
    BagProblem(m,n,flag);
    //delete flag;//這個地方犯了一個原則性的錯誤 new和delete成對使用, malloc應該和free成對使用,要不然就會造成記憶體洩露
    free(flag);
    return 0;
 }