组合和---动态规划法解决问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/birduncle/article/details/67633589

题目大意:给定一组候选数(C)(无重复)和目标数(T),找到候选数与T相加的C中的所有独特组合。  的相同重复数目可以选自c无限次数。

注意:

  • 所有数字(包括目标)将为正整数。
  • 解决方案集不能包含重复的组合。

例如,给定候选集[2, 3, 6, 7]和目标7
A解集是:

[ 
  [7],
  [2,2,3] 
]
动态规划法保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间 适合于用动态规划法求解的问题,经分解后得到的 子问题往往不是互相独立 的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解。

算法设计如下:含答案分析

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * 
 * 动态规划法
 *
 */
public class Solution {


public static List<List<Integer>> combinationSum(int[] candidates, int target) {


Arrays.sort(candidates); // 升序排列
List<List<List<Integer>>> dp = new ArrayList<>();
for (int i = 1; i <= target; i++) { // run through all targets from 1 to target
List<List<Integer>> newList = new ArrayList<>(); // combs for curr i
// run through all candidates <= i
for (int j = 0; j < candidates.length && candidates[j] <= i; j++) {
// special case when curr target is equal to curr candidate
if (i == candidates[j])
newList.add(Arrays.asList(candidates[j]));
// if current candidate is less than the target use prev results
else
for (List<Integer> l : dp.get(i - candidates[j] - 1)) {
if (candidates[j] <= l.get(0)) {
System.out.println(candidates[j]+" "+l.get(0));
List<Integer> cl = new ArrayList<>();
cl.add(candidates[j]);
cl.addAll(l);
System.out.println(cl);
newList.add(cl);
}
}
}
System.out.println(newList);
dp.add(newList);
}
return dp.get(target - 1);
}


public static void main(String[] args) {




int [] nums={2, 3, 6, 7};
int target=7;
System.out.println(combinationSum(nums,target));
}


}

结果输出:

[]
[[2]]
[[3]]
2 2
[2, 2]
[[2, 2]]
2 3
[2, 3]
[[2, 3]]
2 2
[2, 2, 2]
3 3
[3, 3]
[[2, 2, 2], [3, 3], [6]]
2 2
[2, 2, 3]
[[2, 2, 3], [7]]
[[2, 2, 3], [7]]

读者可以依据题目输出进行分析本题中动态规划算法的使用方式

猜你喜欢

转载自blog.csdn.net/birduncle/article/details/67633589