1、递归实现(参考:https://blog.csdn.net/hit_lk/article/details/53967627)

 1 public class Test {
 2  
 3     @org.junit.Test
 4     public void test() {
 5         System.out.println("方案数:" + getAllSchemeNum(new int[]{ 5, 5, 5, 2, 3 }, 15));
 6     } // out : 方案数:4
 7 
 8     /**
 9      * 从数组中选择和为sum的任意个数的组合数
10      */
11     public static int getAllSchemeNum(int[] arr, int sum) {
12         int count = 0;
13         // 将 选择一个数的组合数、选择两个数的组合数、...选择n个数的组合数 相加
14         for (int numToSelect = 1; numToSelect <= arr.length; numToSelect++) {
15             count += getSchemeNumByNumToSelect(arr, numToSelect, sum, 0);
16         }
17         return count;
18     }
19     
20     /**
21      * 求【从数组的[arr[index], arr[length-1]]片段中获取和为sumToSelect的numToSelect个数】的方案数
22      * @param arr 数组
23      * @param numToSelect 还需要选择的数的个数
24      * @param sumToSelect 还需要选择数之和
25      * @param index 可选的范围的左边界
26      * @return
27      */
28     public static int getSchemeNumByNumToSelect(int[] arr, int numToSelect, int sumToSelect, int index) {
29         int count = 0;
30         // 递归出口,如果数全部选择完成,则只需判定sumToSelect是否为零,如果为零,符合条件,返回1,否则返回0
31         if (numToSelect == 0) {
32             return sumToSelect == 0 ? 1 : 0;
33         }
34         /* 
35          * 将问题按选择的第一个数的不同做分解,第一个数可选的范围为[index, arr.length - numToSelect],
36          * 所以就分解成了(arr.length - numToSelect - index + 1)个子问题。可为什么可选下标的右边界是
37          * (arr.length - numToSelect)呢?是因为如果第一个数的下标是(arr.length - numToSelect + 1),
38          * 那么后面只剩(numToSelect - 2)个位置,是不够放下剩余的(numToSelect - 1)个值的。
39          */
40         for (int i = index; i <= arr.length - numToSelect; i++) {
41             if (arr[i] <= sumToSelect) {
42                 /*
43                  * 选择了第一个数arr[i],还需要在剩余数组片段中选择和为(sumToSelect-arr[i])
44                  * 的(numToSelect-1)个数。
45                  * >> 需要递归
46                  */
47                 count += getSchemeNumByNumToSelect(arr, numToSelect - 1, sumToSelect - arr[i], i + 1);
48             }
49         }
50         return count;
51     }
52 }
View Code

相关文章:

  • 2021-06-16
  • 2022-01-01
  • 2021-11-27
  • 2021-12-27
  • 2022-12-23
  • 2021-07-29
  • 2022-02-09
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-22
  • 2022-02-17
  • 2022-12-23
相关资源
相似解决方案