LintCode刷题笔记-- BackpackII
标记:
动态规划
问题描述:
Given n items with size Ai, an integer m denotes the size of a backpack. How full you can fill this backpack?
Example
If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select [2, 3, 5], so that the max size we can fill this backpack is 10. If the backpack size is 12. we can select [2, 3, 7] so that we can fulfill the backpack.
You function should return the max size we can fill in the given backpack.
解题方法:
快要死了,自己想了将近3个小时,居然卡在了如何保持物品放入的唯一性上了,中间用了标记位,哈希集的方法来解决都宣告失败。这一道题还是还是典型的动态规划的背包问题。今天已经可以很自然的划分出子问题来了,并且可以想到利用矩阵的数据结构来存储子状态,并且利用子状态的解来进一步解决问题。但是关于子问题之间的关系和递推方程的领悟还需要进一步的练习,毕竟动态规划是最难的,不是可能轻易领悟的。再一次向九章算法的答案致敬(真是太牛逼了!如果不看这个答案想死了我也想不出这样的解法来。)
好的言归正传,下面是解题思路:
1.划分子问题:
这一题的主问题是什么?非常典型的背包问题的变种。一列物品放入背包之中怎么可以使放入物品达到最大重量,这一问题与先前解决的问题最大的不同在于所有放入的物品是唯一的,就是只能放一次。当然子问题划分与之前并没有什么很大的变化,还是从物品个数和最大重量的两个向量上来划分。列出物品数量*最大重量的矩阵dp[0....i][0....m],期中dp[i][j]所代表的意义在于在最大重量为j时,同时又i种物品可以选,是否存在恰好的有效解,即正好可以有几样物品的重量之和等于当前所给的最大重量。所以dp这一矩阵的数据类型设置为boolean。
2.初始状态定义:
对于所有情况开始都是未知,所以dp整个矩阵可以定义为false,即开始都不存在恰好的解决方案
dp[0][0] = true 作为一个恒成立的情况,即0个物品0个重量时是存在的。
3.子问题之间的关系(递推方程):
这一部分也是所有动态规划最难,最精妙的地方,一个人的逻辑如何,算法能力如何,基本都体现在这一步。
如果在重量j上存在j大于当前物品集合A[i]的重量且在前一物品集合中j-A[i]的位置上也存在恰好解:
例如:[3,4,8,5]四个物品最大的重量时10
0.在0个物品中,重量为0时存在恰好解
1.在只有3的一个物品的情况下重量为0,3时存在恰好解。
2.在存在3,4两个物品的情况下重量为3,4,7时存在恰好解
3.在存在3,4,8三个物品时重量为3,4,7时存在恰好解
4.在存在3,4,8,5三个物品重量为3,4,7,9时存在恰好解
在2中判断重量为7时是否存在恰好解会先判断1中7-4=3的位置是否存在恰好解,若存在此处恰好加上物品4等于7.
若不满足要求则与前一物品情况相同
4.终止状态:
当遍历完全部情况以后,再对存在所有物品的情况中,在不同重量上进行遍历,返回存在恰好解的最大重量,则为题目的解。
5.参考代码:
public int backPack(int m, int[] A) {
// write your code here
boolean[][] dp = new boolean[A.length+1][m+1];
for(int i = 0; i<=A.length; i++){
for(int j = 0; j<=m; j++){
dp[i][j] = false;
}
}
dp[0][0] = true;
for(int i = 0; i<A.length; i++){
for(int j=0; j<=m; j++){
dp[i+1][j] = dp[i][j];
if(j>=A[i]&&dp[i][j-A[i]]){
dp[i+1][j] = true;
}
}
}
for(int i=m; i>=0; i--){
if(dp[A.length][i]){
return i;
}
}
return 0;
}
LintCode刷题笔记-- BackpackII的更多相关文章
- lintcode刷题笔记(一)
最近开始刷lintcode,记录下自己的答案,数字即为lintcode题目号,语言为python3,坚持日拱一卒吧... (一). 回文字符窜问题(Palindrome problem) 627. L ...
- LintCode刷题笔记-- LongestCommonSquence
标签:动态规划 题目描述: Given two strings, find the longest common subsequence (LCS). Your code should return ...
- LintCode刷题笔记-- PaintHouse 1&2
标签: 动态规划 题目描述: There are a row of n houses, each house can be painted with one of the k colors. The ...
- LintCode刷题笔记-- Maximum Product Subarray
标签: 动态规划 描述: Find the contiguous subarray within an array (containing at least one number) which has ...
- LintCode刷题笔记-- Maximal Square
标签:动态规划 题目描述: Given a 2D binary matrix filled with 0's and 1's, find the largest square containing a ...
- LintCode刷题笔记-- Edit distance
标签:动态规划 描述: Given two words word1 and word2, find the minimum number of steps required to convert wo ...
- LintCode刷题笔记-- Distinct Subsequences
标签:动态规划 题目描述: Given a string S and a string T, count the number of distinct subsequences of T in S. ...
- LintCode刷题笔记-- BackpackIV
标签: 动态规划 描述: Given an integer array nums with all positive numbers and no duplicates, find the numbe ...
- LintCode刷题笔记-- BackpackIII
标签:动态规划 问题描述: Given n items with size Ai and value Vi, and a backpack with size m. What's the maximu ...
随机推荐
- 左神算法进阶班8_1数组中累加和小于等于aim的最长子数组
[题目] 给定一个数组arr,全是正数:一个整数aim,求累加和小于等于aim的,最长子数组,要求额外空间复杂度O(1),时间复杂度O(N) [题解] 使用窗口: 双指针,当sum <= aim ...
- jun引导1.04可以让N3050支持6.2
1.03引导用在3050可以安装 但是安装后找不到dsm 需要手动插拔电源才可以解决 偶尔还会死机 1.04可以引导3050安装6.2 23739 安装24922正常,但是moments传照片后会死机 ...
- Python学习day12-函数基础(2)
<!doctype html>day12博客 figure:last-child { margin-bottom: 0.5rem; } #write ol, #write ul { pos ...
- 关于排序--sort()和qsort()使用
一.sort()函数的使用 使用sort()函数的时候要加上头文件#include<algorithm>和using namespace std. 这个函数接收两个或者三个参数. 第一个参 ...
- Spring Boot Starter自定义实现三步曲
实现自定义的spring boot starter,只需要三步: 1.一个Bean 2.一个自动配置类 3.一个META-INF/spring.factories配置文件 下面用代码演示这三步. 项目 ...
- 全栈之路-微信小程序-架构总览
第一阶段是用来学习小程序开发的,这个就相当于PC端的网站吧,只不过现在依靠微信强大的流量来将业务搬移到小程序中,对于企业来说,这是一种很好的发展方向,既减少了开发成本,又减少了推广成本,小程序是很被人 ...
- select 下拉框多选
需要引入插件:fselect.js (此插件依赖jQ) 和 fselect.css 下载 点击查看在线演示地址 //html<select class="demo" mul ...
- linux学习(二)-----Linux 的目录结构、远程登录、vi和vim
linux目录结构 基本介绍 linux 的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录“/”,然后在此 目录下再创建其他的目录. 目录结构具体介绍 Linux 目录总结 1.lin ...
- JDK配置环境变量 (JDK安装成功后进行配置)
"我的电脑" -- 右键"属性" --- "高级系统设置" --- “环境变量” 第一步:配置 JAVA_HOME 变量 找到 变量 ...
- IO流13 --- 转换流实现文件复制 --- 技术搬运工(尚硅谷)
InputStreamReader 将字节输入流转换为字符输入流 OutputStreamWriter 将字符输出流转换为字节输出流 @Test public void test2() { //转换流 ...