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

 public class Test {

     @org.junit.Test
public void test() {
System.out.println("方案数:" + getAllSchemeNum(new int[]{ 5, 5, 5, 2, 3 }, 15));
} // out : 方案数:4 /**
* 从数组中选择和为sum的任意个数的组合数
*/
public static int getAllSchemeNum(int[] arr, int sum) {
int count = 0;
// 将 选择一个数的组合数、选择两个数的组合数、...选择n个数的组合数 相加
for (int numToSelect = 1; numToSelect <= arr.length; numToSelect++) {
count += getSchemeNumByNumToSelect(arr, numToSelect, sum, 0);
}
return count;
} /**
* 求【从数组的[arr[index], arr[length-1]]片段中获取和为sumToSelect的numToSelect个数】的方案数
* @param arr 数组
* @param numToSelect 还需要选择的数的个数
* @param sumToSelect 还需要选择数之和
* @param index 可选的范围的左边界
* @return
*/
public static int getSchemeNumByNumToSelect(int[] arr, int numToSelect, int sumToSelect, int index) {
int count = 0;
// 递归出口,如果数全部选择完成,则只需判定sumToSelect是否为零,如果为零,符合条件,返回1,否则返回0
if (numToSelect == 0) {
return sumToSelect == 0 ? 1 : 0;
}
/*
* 将问题按选择的第一个数的不同做分解,第一个数可选的范围为[index, arr.length - numToSelect],
* 所以就分解成了(arr.length - numToSelect - index + 1)个子问题。可为什么可选下标的右边界是
* (arr.length - numToSelect)呢?是因为如果第一个数的下标是(arr.length - numToSelect + 1),
* 那么后面只剩(numToSelect - 2)个位置,是不够放下剩余的(numToSelect - 1)个值的。
*/
for (int i = index; i <= arr.length - numToSelect; i++) {
if (arr[i] <= sumToSelect) {
/*
* 选择了第一个数arr[i],还需要在剩余数组片段中选择和为(sumToSelect-arr[i])
* 的(numToSelect-1)个数。
* >> 需要递归
*/
count += getSchemeNumByNumToSelect(arr, numToSelect - 1, sumToSelect - arr[i], i + 1);
}
}
return count;
}
}

2、动态规划dp[][]

 @Test
public void test1() {
// 指定输入 >>
int[] arr = { 5, 5, 10, 2, 3 };
int sum = 15;
// ================================================ // 初始化dp二维数组 【dp[i][j]表示用前i个数组成和为j的方案个数】
int rows = arr.length + 1;
int cols = sum + 1;
int[][] dp = new int[rows][cols];
// 初始化dp的第一列,用前i个数组成和为0的方案都只有1种,就是什么都不取;
for (int i = 0; i < rows; i++) {
dp[i][0] = 1;
}
// 初始化dp的第一行,用0个元素不能组成1~sum
for (int j = 1; j <= sum; j++) {
dp[0][j] = 0;
} System.out.println("-- 处理前dp:");
for (int i = 0; i < rows; i++) {
System.out.println((i > 0 ? arr[i - 1] : "附加0") + "\t" + Arrays.toString(dp[i]));
}
System.out.println(); // 一行行的计算dp中每个元素的值
//System.out.println("附加0 \t"+Arrays.toString(dp[0]));
for (int i = 1; i < rows; i++) {
for (int j = 1; j <= sum; j++) {
/*
* 用前i个数来组成和为j的组合,所有成功的组合可分下面两种情况:
* 1、 组合中不包含第i个数 ,即只用前i-1个数来组成和为j的组合。
* 2、组合中包含第i个数,这要求第i个数不能比和大(前i-1个数要组成和为:j-第i个数)。
*/
dp[i][j] = dp[i - 1][j];
if (arr[i-1] <= j) { // 第i个数为arr[i-1]
dp[i][j] += dp[i - 1][j - arr[i-1]];
}
}
//System.out.println(arr[i-1]+"\t"+Arrays.toString(dp[i]));
} System.out.println("-- 处理后dp:");
for (int i = 0; i < rows; i++) {
System.out.println((i > 0 ? arr[i - 1] : "附加0") + "\t" + Arrays.toString(dp[i]));
}
System.out.println("答案:" + dp[rows-1][sum]);
}
/* out:
-- 处理前dp:
附加0 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
5 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
5 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
10 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
2 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
3 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -- 处理后dp:
附加0 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
5 [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
5 [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
10 [1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2]
2 [1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 0, 2, 0, 0, 2]
3 [1, 0, 1, 1, 0, 3, 0, 2, 2, 0, 4, 0, 2, 2, 0, 4]
答案:4
*/

【算法习题】正整数数组中和为sum的任意个数的组合数的更多相关文章

  1. 【算法习题】数组中任意2个(3个)数的和为sum的组合

    题1.给定一个int数组,一个数sum,求数组中和为sum的任意2个数的组合 @Test public void test_find2() { int[] arr = { -1, 0, 2, 3, 4 ...

  2. (回溯法)数组中和为S的N个数

    Given a list of numbers, find the number of tuples of size N that add to S. for example in the list ...

  3. Two sum(给定一个无重复数组和目标值,查找数组中和为目标值的两个数,并输出其下标)

    示例: nums = [1,2,5,7] target = [6] return [0,2] Python解决方案1: def twoSum(nums, target): ""&q ...

  4. 18. 4Sum -- 找到数组中和为target的4个数

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  5. 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数 例如给定nums = [2,7,11,15],target = 9

    python解决方案 nums = [1,2,3,4,5,6] #假如这是给定的数组 target = 9 #假如这是给定的目标值 num_list = [] #用来装结果的容器 def run(nu ...

  6. 1001 数组中和等于K的数对 1002 数塔取数问题 1003 阶乘后面0的数量 1004 n^n的末位数字 1009 数字1的数量

    1001 数组中和等于K的数对 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 给出一个整数K和一个无序数组A,A的元素为N个互不相同的整数,找出数组A中所有和等于K ...

  7. c++刷题(12/100)无序数组中和为定值的最长子数组

    题目一: 最短无序连续子数组 给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序. 你找到的子数组应是最短的,请输出它的长度. 示例 1: 输入: ...

  8. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  9. 【bzoj3289】Mato的文件管理 离散化+莫队算法+树状数组

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805224.html 题目描述 Mato同学从各路神犇以各种方式(你们懂的)收集了许多资料,这些资料一共有n份,每份 ...

随机推荐

  1. Golang微服务:Micro介绍

    官方文档地址 https://micro.mu/docs/index.html Tookit API HTTP接入网关.反向代理或将HTTP转为RPC请求调用后端服务 Web 一个web应用程序,默认 ...

  2. javaScript 深拷贝、浅拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...

  3. oracle控制文件问题

    下午时连接数据库突然发现连不上了,监听报错找不到服务,于是登录数据库所在服务器,查看监听状态,oracle:lsnrctl status 监听状态正常,登入数据库查看[oracle@frkdb1 ~] ...

  4. js的组成部分

    ECMAScript js基本语法与标准 DOM Document Object Model文档对象模型 BOM Browser Object Model浏览器对象模型

  5. js 文件异步上传 显示进度条 显示上传速度 预览文件

    通常文件异步提交有几个关键 1.支持拖拽放入文件.2.限制文件格式.3.预览图片文件.4.上传进度,速度等,上传途中取消上传.5.数据与文件同时上传 现在开始笔记: 需要一个最基础的元素<inp ...

  6. Kali Linux系统的安装、配置、使用

    这个随便写的,随便看看就好,主要给讲一下安装过程 这里因为我物理机装的本来就是kali.所以懒得重装了,直接拿虚拟机演示一下 物理机安装kali的话,推荐使用rufus使用dd模式刻盘,不会造成之后的 ...

  7. https://www.cnblogs.com/yudanqu/p/9467803.html

    https://www.cnblogs.com/yudanqu/p/9467803.html

  8. Python实例之抓取网易云课堂搜索数据(post方式json型数据)并保存到数据库

    本实例实现了抓取网易云课堂中以‘java’为关键字的搜索结果,经详细查看请求的方式为post,请求的结果为JSON数据 具体实现代码如下: import requests import json im ...

  9. 20175202 《Java程序设计》第五周学习总结

    20175209 2018-2019-2 <Java程序设计>第五周学习总结 教材知识点总结 1.接口声明: 使用关键字interface来定义接口. 定义接口时使用关键字interfac ...

  10. 2018-2019-2 网络对抗技术 20165308 Exp2 后门原理与实践

    2018-2019-2 网络对抗技术 20165308 Exp2 后门原理与实践 1.实验内容 (3.5分) (1)使用netcat获取主机操作Shell,cron启动 (0.5分) (2)使用soc ...