1)狀態:揹包容量、可選擇的物品
2)選擇:裝或者不裝
3)定義dp陣列:dp[i][j]=x,前i個物品,容量為j時的揹包。x為true/false
4)初始化:在沒有任何物品裝入時的合法狀態
要求恰好裝滿:dp[i][0]只有容量為0的揹包才能滿足
沒有要求恰好裝滿:dp[0][i]即沒有任何物品放入
base case:
dp[i][0]=ture裝滿
dp[0][i]=false沒有物品
5)狀態轉移方程:(角度:分類討論)
不把這第i個物品裝入揹包,那麼是否能夠恰好裝滿揹包,取決於上乙個狀態dp[i-1][j],繼承之前的結果。
把這第i個物品裝入了揹包,那麼是否能夠恰好裝滿揹包,取決於狀態dp[i - 1][j-nums[i-1]]。(上個狀態的揹包餘量)
(如果裝了第i個物品,就要看揹包的剩餘重量j - nums[i-1]限制下是否能夠被恰好裝滿。)
i是從 1 開始的,而陣列索引是從 0 開始的,所以第i個物品的重量應該是nums[i-1]。
6)狀態壓縮:
「狀態陣列」從二維降到一維,減少空間複雜度。
壓縮到一維時,要採用逆序。因為dp[j]使用的是上乙個陣列內的元素,若果從前往後,當前陣列的改變會對後面陣列造成影響,所以從後向前可以避免這個事情的發生。
給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。
注意:每個陣列中的元素不會超過 100
陣列的大小不會超過 200
示例 1:
輸入: [1, 5, 11, 5]
輸出: true
解釋: 陣列可以分割成 [1, 5, 5] 和 [11].
示例 2:
輸入: [1, 2, 3, 5]
輸出: false
解釋: 陣列不能分割成兩個元素和相等的子集.
題解:
1)是否可以從輸入陣列中挑選出一些正整數,使得這些數的和等於整個陣列元素的和的一半。陣列的和一定是偶數。
轉化為0-1揹包問題
給乙個可裝載重量為sum/2的揹包和n個物品,每個物品的重量為nums[i]。現在裝物品,是否存在一種裝法,能夠恰好將揹包裝滿
2)dp[i][j]表示從陣列[0,i]下標範圍內選取若干正整數,是否存在一種方案使得其和為j
3)建立乙個[2222][3333]的二維陣列
vectordp(2222,vector(3333))
建立乙個bool型二維陣列
vectordp(n + 1, vector(sum + 1, false));
全部初始化為false
4)行[i]列[j]
i每進行一輪迭代dp【j】相當於dp【i-1】【j】
};壓縮到一維時,要採用逆序。dp[j] = dp[j] || dp[j - nums[i]] 可以理解為 dp[j] (新)= dp[j] (舊) || dp[j - nums[i]] (舊),如果採用正序的話 dp[j - nums[i]]會被之前的操作更新為新值
揹包問題 416 分割等和子集
0 1揹包問題。dp陣列中dp i w 的含義。dp i w 的定義如下 對於前i個物品,當前揹包的容量為w,這種情況下可以裝的最大價值是dp i w 如果你沒有把這第i個物品裝入揹包,那麼很顯然,最大價值dp i w 應該等於dp i 1 w 如果你把這第i個物品裝入了揹包,那麼dp i w 應該...
Leetcode416 分割等和子集 01揹包變種
暴力解法 public final boolean canpartition1 int nums 剪枝 int sum 0 int max 0 for int i 0 i nums.length i if sum 2 0 int target sum 2 if max target if max t...
力扣 416 分割等和子集 01揹包 暴力
思路一 dpdp dp,首先計算陣列元素的和,如果為奇數則一定不能滿足題意,否則子集的和就等於總和的一半,假設為hal fhalf half 那麼問題轉換成 是否可以從陣列中任取一些數字使得它們的和為hal fhalf half 01 0101 揹包可解,dp i 1 dp i 1 dp i 1說明...