Mysql日誌-初步學習
阿新 • • 發佈:2021-08-17
目錄
動態規劃總結
動態規劃中每一個狀態一定是由上一個狀態推匯出來的
明確兩個點,狀態和選擇
解題步驟
1.確定dp陣列以及下標的含義
2.確定遞推公式
3.dp陣列如何初始化
4.確定遍歷順序
5.舉例推導dp陣列
有一些情況遞推公式決定了dp陣列要如何初始化,所以先確定遞推公式。
如何debug
最好辦法是把dp陣列打印出來,觀察是否與解題步驟5所示自己推導的陣列一樣。
如果一樣,那麼就是遞推公式、初始化或者遍歷順序有問題。
如果不一樣,就是程式碼實現細節有問題。
揹包問題
重點是01揹包與完全揹包
01揹包
有N件物品和一個最多能放重量為W 的揹包。第i件物品的重量是weight[i],得到的價值是value[i] 。每件物品只能用一次,求解將哪些物品裝入揹包裡物品價值總和最大。
初始化陣列
倒敘遍歷,保證物品0只被放入一次
/* dp[0][j],存放編號0的物品的時候,各個容量的揹包所能存放的最大價值。 這裡將的是0號物品,就不用考慮dp[i - 1][j], */ // 倒敘遍歷 for (int j = bagWeight; j >= weight[0]; j--) { dp[0][j] = dp[0][j - weight[0]] + value[0]; // 初始化i為0時候的情況 } //感覺這裡可以直接初始化 for (int j = weight[0]; j >= weight[0]; j++) { dp[0][j] = value[0]; // 初始化i為0時候的情況 }
遍歷順序
有兩個遍歷維度:物品與揹包重量
先遍歷物品
for(int i = 1; i < weight.size(); i++) { // 遍歷物品
for(int j = 0; j <= bagWeight; j++) { // 遍歷揹包容量
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
}
}
一維寫法
void test_1_wei_bag_problem() {
vector<int> weight = {1, 3, 4};
vector<int> value = {15, 20, 30};
int bagWeight = 4;
// 初始化
vector<int> dp(bagWeight + 1, 0);
for(int i = 0; i < weight.size(); i++) { // 遍歷物品
for(int j = bagWeight; j >= weight[i]; j--) { // 遍歷揹包容量
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
cout << dp[bagWeight] << endl;
}
int main() {
test_1_wei_bag_problem();
}