0 1揹包問題 416 分割等和子集

2021-10-25 17:58:12 字數 2024 閱讀 2032

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說明...