代码随想录算法训练营Day41 | 01背包问题,你该了解这些! 01背包问题,你该了解这些! 滚动数组 416. 分割等和子集
卡码网 46 背包问题,你该了解这些!
题目链接:卡码网 46 背包问题,你该了解这些!
思路:
用重量和数量依次遍历 i为个数, j为容量
#include <bits/stdc++.h>
using namespace std;
int n;
int bagweight;
void slove(){
vector<int> weight(n,0);
vector<int> value(n,0);
for(int i=0; i<n; i++){
cin>>weight[i];
}
for(int i=0; i<n; i++){
cin>>value[i];
}
vector<vector<int>> dp(n, vector<int>(bagweight+1,0));
for(int i=weight[0]; i<=bagweight;i++){
dp[0][i] = value[0];
}
for(int i=1; i<n; i++){
for(int j=1; 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[n-1][bagweight] << endl;
}
int main(){
while(cin>>n>>bagweight){
slove();
}
return 0;
}
注意 :
- 个数为n即可
LeetCode 卡码网 46 背包问题(滚动数组)
题目链接:LeetCode 卡码网 46 背包问题
思路:
先定义dp的含义
在定义转移方程
再初始化
最后遍历
#include <iostream>
#include <vector>
using namespace std;
void solve(int n, int space){
vector<int> weight(n);
vector<int> value(n);
for(int i=0; i<n; i++){
cin>>weight[i];
}
for(int i=0; i<n; i++){
cin>>value[i];
}
vector<int> dp(space+1);
dp[0] = 0;
for(int i=0; i<n; i++){
for(int j=space; j>=weight[i]; j--){
dp[j] = max(dp[j], dp[j-weight[i]]+value[i]);
}
}
cout << dp[space];
}
int main(){
int n;
int space;
cin >> n >> space;
solve(n, space);
return 0;
}
注意 :
- 遍历的顺序,从大到小,这样才不会覆盖value
LeetCode 416. 分割等和子集
题目链接:LeetCode 416. 分割等和子集
思路:
和背包问题一样,weight和value一样视作。
class Solution {
public:
bool canPartition(vector<int>& nums) {
int target = 0;
for(int num:nums) target += num;
if(target%2) return false;
target /= 2;
int n = nums.size();
vector<int> dp(target+1);
dp[0] = 0;
for(int i=1; i<n; 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;
}
};
注意 :
- dp的长度为capcity;