01背包问题,你该了解这些!
五部曲:
- dp数组下标及含义:dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少
- dp数组初始化:dp[i][0]=0; j < weight[0]的时,dp[0][j]=0,当j >= weight[0]时,dp[0][j] =value[0]
- 递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
- 遍历方向:先遍历物品在遍历背包
- dp数组推到举例:来自代码随想录
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, bagweight;
while(cin >> n >> bagweight) {
vector<int> weight(n,0);
vector<int> value(n,0);
for(int i=0;i<n;i++){
cin>>weight[i];
}
for(int j =0;j<n;j++){
cin>>value[j];
}
vector<vector<int>> dp(weight.size(),vector<int>(bagweight+1,0));
for(int j =weight[0];j<=bagweight;j++){
dp[0][j] = value[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]);
}
}
cout << dp[weight.size() - 1][bagweight] << endl;
}
return 0;
}
01背包问题,你该了解这些! 滚动数组
五部曲:
-
dp数组下标及含义:dp[j]表示容量为j的背包,所背的物品价值可以最大为dp[j]。
-
dp数组初始化:都初始为0
-
递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
-
遍历方向:先遍历物品再反向遍历背包
#include <iostream>
#include <vector>
using namespace std;int main() {
int M, N;
cin >> M >> N;vector<int> costs(M); vector<int> values(M); for (int i = 0; i < M; i++) { cin >> costs[i]; } for (int j = 0; j < M; j++) { cin >> values[j]; } vector<int> dp(N + 1, 0); for (int i = 0; i < M; ++i) { for (int j = N; j >= costs[i]; --j) { dp[j] = max(dp[j], dp[j - costs[i]] + values[i]); } } cout << dp[N] << endl; return 0;
}
416. 分割等和子集
本题用01背包问题解法求解,相当于背包的体积target=sum/2,物品就是元素。
五部曲:
-
dp数组下标及含义:dp[j]表示容量为j的背包,所背的物品价值可以最大为dp[j]。
-
dp数组初始化:都初始为0
-
递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
-
遍历方向:先遍历物品再反向遍历背包
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
vector<int> dp(10001, 0);
for (int i = 0; i < nums.size(); i++) {
sum += nums[i];
}
if (sum % 2 == 1)
return false;
int target = sum / 2;for (int i = 0; i < nums.size(); i++) { for (int j = target; j >= nums[i]; j--) { dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]); } } if (dp[target] == target) return true; return false; }
};