【100題】第二十一題(中興面試題)

來源:互聯網
上載者:User

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

二,解釋:比如輸入m=4  n=4 則輸出為:4

                                                                   1+3   而2+2不正確,因為重複輸出數字了

                  中心思想:1)如果1+2+3+……+n<m 則不存在這個數

                                    2)如果m<n 則應該讓n=m //因為m--->n之間的數都已經大於m了 沒必要再計算了

                                    3)如果m=n 輸出n

                                    4)如果m>n   遞迴迴圈

                  源碼採用原型:0-1背包問題

                                 參考部落格:http://blog.csdn.net/tianshuai11/article/details/7025464

三,源碼:(類似源碼五)

#include<list>#include<iostream>  using namespace std;    list<int> list1;  void find_factor(int sum, int n)   {      // 遞迴出口      if(n <= 0 || sum <= 0)          return;            // 輸出找到的結果      if(sum == n)      {          // 反轉list          list1.reverse();          for(list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)              cout << *iter << " + ";          cout << n << endl;          list1.reverse();          }            list1.push_front(n);      //典型的01背包問題      find_factor(sum-n, n-1);   //放n,n-1個數填滿sum-n      list1.pop_front();      find_factor(sum, n-1);     //不放n,n-1個數填滿sum   }    int main()  {      int sum, n;      cout << "請輸入你要等於多少的數值sum:" << endl;      cin >> sum;      cout << "請輸入你要從1.....n數列中取值的n:" << endl;      cin >> n;      cout << "所有可能的序列,如下:" << endl;      find_factor(sum,n);      return 0;  }  


四,源碼(java方法)

/** * 輸入兩個整數 n 和 m,從數列1,2,3.......n 中 隨意取幾個數,使其和等於 m ,要求將其中所有的可能組合列出來.e.g n=6,m=6   1,2,3    2,4    1,5n= * @author wangxm */public class Comp {static void getAllComp(int n,int m){String pre = m+"=";int theMax = (1+n)*n/2;if(theMax<m){System.out.println("不存在該數!");}else{for(int i=1;i<=m/2;i++){//從1開始計數,列印出兩個數的組合,並且兩數不相等if(i != m-i)System.out.println(pre+i+"+"+(m-i));//調用遞迴,繼續求得大於2個數的組合getTheResult(m-i,pre+i,i);}}}//調用遞迴,繼續求得大於2個數的組合,j為組合中已用過的數,所以取大於該數的。static void getTheResult(int m,String pre,int j){for(int i=j+1;i<=m/2;i++){if(i != m-i)System.out.println(pre+"+"+i+"+"+(m-i));getTheResult(m-i,pre+"+"+i,i);}}public static void main(String[] args) {getAllComp(3,6);}}

五,源碼(容易理解)

#include <iostream>   using namespace std; int length;   void PrintSolution(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;               PrintSolution(flag);            flag[n-1]=0;         }       flag[n-1]=1; //n先放入背包中BagProblem(m-n,n-1,flag);   //剩餘空間為 m-n  可以取的背包為 1->n-1flag[n-1]=0;     //n不放入背包中BagProblem(m,n-1,flag); //剩餘空間為 m  可以取的背包為 1->n-1} int main() {    int m,n;     cout<<"please input m and n:"<<endl;   cin>>m>>n;     cout<<"the solution is :"<<endl; length=n;    int *flag=(int *)malloc(sizeof(int)*n);  memset(flag,0,sizeof(int)*n);//注意memset用法及區分sizeof(flag)/sizeof(int)*n   BagProblem(m,n,flag);  free(flag);     return 0;   }

【0-1背包公式】opt[i][v] = max(opt[i-1][v] , opt[i-1][v-c[i]] + w[i]) 
     解釋如下:
              opt[i-1][v] 表示第i件物品不裝入背包中,而opt[i-1][v-c[i]] + w[i] 表示第i件物品裝入背包中。

對應之後:n為物品  m為背包容積,這裡相當於求“所有可能的裝滿的裝法”。忽略了價值的計算即沒有真正計算出那種裝法最佳

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.