和為指定數的組合個數
阿新 • • 發佈:2019-01-07
問題:
輸入兩個整數 n 和 m,從數列1,2,3…….n 中 隨意取幾個數,
使其和等於 m ,要求將其中所有的可能組合列出來
解答:
排序 + 0-1揹包:
若第i個數放入,剩下0~i-1個數取出sum-ai
否則0~i-1取出sum
/**
* 從i個數裡取出和為sum的組合個數
* 不去重
*
* @param i
* @param sum
*/
private static int fun(int i, int sum, int a[]) {
if (i < 0 || sum <= 0 ) return 0;
int cnt = 0;
if (a[i] == sum) cnt++;
cnt += fun(i - 1, sum - a[i], a) + fun(i - 1, sum, a);
return cnt;
}
/**
* 從i個數裡取出和為sum的組合個數
* 去重
*
* @param i
* @param sum
*/
private static Set<List<Integer>> fun(int i, int sum, int a[]) {
if (i < 0 || sum <= 0) return null;
Set<List<Integer>> ans = new HashSet<>();
if (a[i] == sum) {
List<Integer> list=new ArrayList<>();
list.add(a[i]);
ans.add(list);
}
Set<List<Integer>> next1 = fun(i - 1 , sum - a[i], a);
if (next1 != null) {
for (List<Integer> list : next1) {
list.add(Integer.valueOf(a[i]));
}
ans.addAll(next1);
}
Set<List<Integer>> next2 = fun(i - 1, sum, a);
if (next2 != null) {
ans.addAll(next2);
}
return ans;
}