【LintCode】Backpack 揹包問題
在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小為m,每個物品的大小為A[i]。
樣例
如果有4個物品[2, 3, 5, 7]
如果揹包的大小為11,可以選擇[2, 3, 5]裝入揹包,最多可以裝滿10的空間。
如果揹包的大小為12,可以選擇[2, 3, 7]裝入揹包,最多可以裝滿12的空間。
函式需要返回最多能裝滿的空間大小。
注意
你不可以將物品進行切割。
舉例:
如果有4個物品[2, 3, 5, 7],如果揹包的大小為11。問最多能裝多滿?
建動態規劃陣列 dp[A.length][m + 1],A.length行,m+1列
start | j = 0 | j = 1 | j = 2 | j = 3 | j = 4 | j = 5 | j = 6 | j = 7 | j = 8 | j = 9 | j = 10 | j = 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
i = 0 (A[0]=2) | dp[0][0] = 0 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
i = 1 (A[1]=3) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
i = 2 (A[2]=5) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 7 | 8 | 8 | 10 | 10 |
i = 3 (A[3]=7) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 7 | 8 | 9 | 10 | 10 |
dp[i][j]為當揹包總重量為j且有前i個物品時,揹包最多裝滿dp[i][j]的空間。
狀態轉移方程為:dp[i][j] = Math.max(dp[i - 1][j - A[i]] + A[i], dp[i-1][j]);
dp[i - 1][j - A[i]] + A[i]為加入第i個物品後背包的總裝滿空間。
a.為了把第i個物品放進揹包,揹包當然要先騰出至少A[i]的空間,騰出後空間的最多裝滿空間為dp[ i - 1][j - A[i]],再加上第i個物品的空間A[i],即為當揹包總空間為j時,裝入第i個物品揹包的總裝滿空間。
b.當然第i個物品所佔的空間可能比此時揹包的總空間j要大(j < A[i]),此時裝不進第i個物品,因此此時揹包的總裝滿空間為dp[i-1][j]。
c.還有一種可能的情形是,雖然第i個物品能夠裝入包中,但為了把第i個物品裝入而拿出了其他物品,使此時的總裝入空間dp[i-1][j-A[i]] + A[i] < dp[i-1][j]
其他情形:
當j = 0時,dp[i][0] = 0
原題答案即為dp[3][11] = 10,揹包的總空間為11時,四個物品能夠裝入的最大空間為多大。
public class Solution {
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
public int backPack(int m, int[] A) {
int[][] dp = new int[A.length][m + 1];//動態規劃矩陣
for(int i = 0; i < A.length; i ++) {//揹包空間為0時,不管要放第幾個物品,可裝滿的揹包空間為0.
dp[i][0] = 0;
}
for(int j = 1; j < m + 1; j++) {
if(A[0] <= j) {//當第0個物品的空間小於等於當前揹包空間j時
dp[0][j] = A[0];//揹包可裝滿的最大空間是第0個物品的體積
}else {//當第0個物品的空間大於當前揹包空間j時
dp[0][j] = 0;//揹包可裝滿的最大空間是0
}
for(int i = 1; i < A.length; i++) {//當放第1個到第A.length-1個物品時
if(A[i] > j) {//若該物品所佔空間大於揹包總空間(無論怎樣騰揹包空間,該物品無法放入揹包
dp[i][j] = dp[i - 1][j];//揹包可裝滿的最大空間不變
}else {//若該物品所佔空間小於等於揹包總空間,則需將揹包空間騰出至少A[i]後,將該物品放入。放入新物品後背包最大可裝滿空間可能更大,也可能變小大,取大值作為揹包空間為j且放第i個物品時可以有的最大可裝滿空間。
dp[i][j] = Math.max(dp[i-1][j - A[i]] + A[i], dp[i - 1][j]);
}
}
}
return dp[A.length - 1][m];
}
}
相關推薦
【LintCode】Backpack 揹包問題
在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小為m,每個物品的大小為A[i]。 樣例 如果有4個物品[2, 3, 5, 7] 如果揹包的大小為11,可以選擇[2, 3, 5]裝入揹包,最多可以裝滿10的空間。 如果揹包的大小為12,可以選
【LintCode】060.Search Insert Position
spa posit art you sta ger har duplicate earch 題目: Given a sorted array and a target value, return the index if the target is found. If no
【Lintcode】074.First Bad Version
ota class base found sed follow ntc art spa 題目: The code base version is an integer start from 1 to n. One day, someone committed a bad v
【Lintcode】038.Search a 2D Matrix II
ger class duplicate ntc sts ram public win param 題目: Write an efficient algorithm that searches for a value in an m x n matrix, return th
【Lintcode】069.Binary Tree Level Order Traversal
vector pub i++ pre oot order ptr values logs 題目: Given a binary tree, return the level order traversal of its nodes‘ values. (ie, from le
【Lintcode】098.Sort List
col || lin lex strong span tro con pre 題目: Sort a linked list in O(n log n) time using constant space complexity. Example Given 1->3-
【Lintcode】102.Linked List Cycle
node false col lint tro head -s tno cycle 題目: Given a linked list, determine if it has a cycle in it. Example Given -21->10->4->
【Lintcode】099.Reorder List
ive strong linked size reorder right find lan second 題目: Given a singly linked list L: L0 → L1 → … → Ln-1 → Ln reorder it to: L0 → Ln → L
【Lintcode】105.Copy List with Random Pointer
map class node link listnode span public point turn 題目: A linked list is given such that each node contains an additional random pointer
【Lintcode】029.Interleaving String
ngs logs eth str tro determine span lintcode return 題目: Given three strings: s1, s2, s3, determine whether s3 is formed by the interlea
【Lintcode】046.Majority Number
his oot log light ntc else white hit lte 題目: Given an array of integers, the majority number is the number that occurs more than half o
【Lintcode】382.Triangle Count
技巧 初始 運算 panel ron triangle ger numbers 暴力搜索 題目: Given an array of integers, how many three numbers can be found in the array, so that
【Lintcode】364.Trapping Rain Water II
example rom 中心 || als ref reat map href 題目: Given n x m non-negative integers representing an elevation map 2d where the area of each c
【演算法】類揹包問題解決組合數以及其java實現
這是今年迅雷面試題,原題如下: 給定整數n,取若干個1到n的整數可求和等於整數m,程式設計求出所有組合的個數。比如當n=6,m=8時,有四種組合:[2,6], [3,5], [1,2,5], [1,3,4]。限定n和m小於120 輸入描述: 整數n和m 輸
【LintCode】反轉整數
(1) 反轉一個只有3位數的整數。 i 注意事項 你可以假設輸入一定是一個只有三位數的整數,這個整數大於等於100,小於1000。 樣例 123 反轉之後是 321。 900 反轉之後是 9。 標籤 基本實現 相關題目 容易 反轉整數
【Lintcode】加一
題目描述: 給定一個非負數,表示一個數字陣列,在該數的基礎上+1,返回一個新的陣列。 該數字按照大小進行排列,最大的數在列表的最前面。 樣例: 給定 [1,2,3] 表示 123, 返回 [1,2,4]. 給定 [9,9,9] 表示 999, 返回 [
【Lintcode】有效的括號序列
最近比較閒,於是打算刷一些Lintcode的題來提高自己的程式碼功底。 題目描述: 給定一個字串所表示的括號序列,包含以下字元: ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, 判定是否是有效的括號序列。 樣例: 括號必須依照 “()”
【LintCode】1、A + B問題
1、題目:A + B 問題 描述: 給出兩個整數a和b, 求他們的和, 但不能使用 + 等數學運算子。 注意事項: 你不需要從輸入流讀入資料,只需要根據aplusb
【Lintcode】合併排序陣列&& 合併排序陣列 II
題目描述:合併兩個排序的整數陣列A和B變成一個新的陣列。 注意事項 你可以假設A具有足夠的空間(A陣列的大小大於或等於m+n)去新增B中的元素。 樣例:給出 A = [1, 2, 3, empty, empty], B = [4, 5] 合併之後 A 將
【Lintcode】A+B問題
題目描述: 給出兩個整數a和b, 求他們的和, 但不能使用 + 等數學運算子。 注意事項 你不需要從輸入流讀入資料,只需要根據aplusb的兩個引數a和b,計算他們的和並返回就行。 說明: a