本文主要使用一維陣列進行使用
意思:01揹包:代表物品只有兩種狀態,只能使用一次。如,dp[i] = max(dp[i], dp[i - wight[j]] + value[j]) 代表容量為i所獲得的最大利潤。
完全揹包:乙個物品可以使用無限次
技巧:1.如果是0-1揹包,即陣列中的元素不可重複使用,nums放在外迴圈,target在內迴圈,且內迴圈倒序;(原因:倒序,後乙個狀態只依賴前乙個狀態,而nums是有順序的,故只使用了一次)
2.如果是完全揹包,即陣列中的元素可重複使用,nums放在外迴圈,target在內迴圈。且內迴圈正序。
3.如果組合問題需考慮元素之間的順序,需將target放在外迴圈,將nums放在內迴圈。(有順序,按照目標target大小進行遍歷),不考慮順序時,nums放到外環。
基礎模版:
常見的揹包問題有1、組合問題。2、true、false問題。3、最大最小問題(最大和最小問題只需要修改陣列中的預設值)。
模板1:
//01揹包,最大值
dp[0] = 0
for (int i = 0; i < nums.size(); i++)
}
//完全揹包,最大值
dp[0] = 0
for (int i = 0; i < nums.size(); i++)
}
//01揹包,組合問題(後乙個狀態依賴於前乙個狀態,多種前置狀態帶來不同組合數)
dp[0] = 1(組合數)
for (int i = 1; i <= target; i++)
}
//01揹包,能否得到乙個狀態(只要有乙個狀態到達即可)
dp[0] = 1
for (int i = 0; i < nums.size(); i++)
}
1、組合問題:
377. 組合總和 ⅳ
完全揹包常用模板(dp[i] = max(dp[i], dp[i - wight[j]] + value[j])),獲取能得到組合數的最大值,本文題目是獲取組合數,故使用組合模板
int combinationsum4(vector& nums, int target) }}
return dp[target];
}
494. 目標和(未刷)
518. 零錢兌換 ii
組合無序,故將nums放到外迴圈
int change(int amount, vector& coins)
}return dp[amount];
}
2、true、false問題:
139. 單詞拆分(未刷)
416. 分割等和子集
bool canpartition(vector& nums)
if (sum % 2)
sum = sum / 2;
vectordp(sum + 1, 0);
dp[0] = 1;
for (int i = 1; i < nums.size(); i++) }}
if (dp[sum])
return false;
}
我給轉化到最大值
bool canpartition(vector& nums)
if (sum % 2)
sum = sum / 2;
vectordp(sum + 1, 0);
dp[0] = 0;
for (int i = 1; i < nums.size(); i++) }}
if (dp[sum] == sum)
return false;
}
3、最大最小問題:
474. 一和零(未刷)
322. 零錢兌換
int coinchange(vector& coins, int amount) }}
if (dp[amount] != int_max)
return -1;
}
參考: 01揹包,完全揹包
動態規劃 動態規劃的核心是狀態以及狀態轉移方程。需要定義乙個 i,j 狀態以及該狀態的指標函式d i,j 01揹包 有n種物品,每種只有乙個,第i件物品的體積為vi質量為wi。選一些物品裝到體積為c的揹包中,使其體積不超過c的前提下重量最大。namevw abcd e 子問題定義 dp i j 表示...
揹包 01揹包,完全揹包,多重揹包
哈哈 01揹包 f i v max 完全揹包 f i v max 多重揹包 f i v max include include include include include define maxn 1000 using namespace std int n,cap int w maxn 重量 花...
01揹包 完全揹包 多重揹包
01揹包 zeroonepack 有n件物品和乙個容量為v的揹包,每種物品均只有一件。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。include include includeusing namespace std const int n 1000 10 int ...