1. 程式人生 > >【LintCode】Backpack 揹包問題

【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];
    }
}

相關推薦

LintCodeBackpack 揹包問題

在n個物品中挑選若干物品裝入揹包,最多能裝多滿?假設揹包的大小為m,每個物品的大小為A[i]。 樣例 如果有4個物品[2, 3, 5, 7] 如果揹包的大小為11,可以選擇[2, 3, 5]裝入揹包,最多可以裝滿10的空間。 如果揹包的大小為12,可以選

LintCode060.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

Lintcode074.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

Lintcode038.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

Lintcode069.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

Lintcode098.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-

Lintcode102.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->

Lintcode099.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

Lintcode105.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

Lintcode029.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

Lintcode046.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

Lintcode382.Triangle Count

技巧 初始 運算 panel ron triangle ger numbers 暴力搜索 題目: Given an array of integers, how many three numbers can be found in the array, so that

Lintcode364.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 ‘]’, 判定是否是有效的括號序列。 樣例: 括號必須依照 “()”

LintCode1、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 將

LintcodeA+B問題

題目描述: 給出兩個整數a和b, 求他們的和, 但不能使用 + 等數學運算子。 注意事項 你不需要從輸入流讀入資料,只需要根據aplusb的兩個引數a和b,計算他們的和並返回就行。 說明: a