目錄
1 問題描述
輸入兩個整數n和sum,要求從數列1,2,3,...,n中隨意取出幾個數,使得它們的和等於sum,請將其中所有可能的組合列出來。
2 解決方案
上述問題是典型的背包問題的應用,即先找出n個數的所有組合,再在這些組合中尋找組合數相加之和等於sum的組合,並依次輸出這些組合中的數。
具體代碼如下:
package com.liuzhen.array_2; public class ManySumN { /* * 函數功能:以字符串形式返回1~n個數的所有子集,其中0代表不包含其中數字i,1代表 包含其中數字i * 此段代碼是運用反射格雷碼的思想,具體解釋詳見:算法筆記_019:背包問題(Java)
*/ public String[] getAllGroup(int n){ int len = (int) Math.pow(2, n); String[] result = new String[len]; if(n == 1){ result[0] = "0"; result[1] = "1"; return result; } String[] temp = getAllGroup(n-1); for(int i = 0;i < temp.length;i++){ result[i] = "0" + temp[i]; result[len-1-i] = "1" + temp[i]; } return result; } /* * 參數n:代表有1~n的n個不同整數 * 函數功能:打印出1~n中所有隨機組合的幾個數,其相加的和等於sum */ public void printManySumN(int n,int sum){ System.out.println("1~"+n+"個數中,相加之和等於"+sum+"的所有組合數為:"); String[] allGroup = getAllGroup(n); for(int i = 0;i < allGroup.length;i++){ char[] temp = allGroup[i].toCharArray(); int tempSum = 0; for(int j = 0;j < temp.length;j++){ if(temp[j] == '1') tempSum += (j+1); } if(tempSum == sum){ for(int j = 0;j < temp.length;j++){ if(temp[j] == '1') System.out.print((j+1)+" "); } System.out.println(); } } } public static void main(String[] args){ ManySumN test = new ManySumN(); test.printManySumN(10, 16); } }
運行結果:
1~10個數中,相加之和等於16的所有組合數為:
7 9
6 10
4 5 7
3 4 9
3 5 8
3 6 7
2 3 5 6
2 3 4 7
2 4 10
2 5 9
2 6 8
1 2 6 7
1 2 5 8
1 2 4 9
1 2 3 4 6
1 2 3 10
1 3 5 7
1 3 4 8
1 4 5 6
1 5 10
1 6 9
1 7 8