思路:这是一道01背包的问题,首先考虑
dp
数组,一个二维的dp[i][j]
其i的含义是什么呢?物品的数量,j是背包的容量,dp[i][j]
表示装了i件物品,用了j这么大的空间,里面的最大价值是多少。递推公式:分为几种情况,一种是能装下,但是不一定装进去,价值比原来的大,故此时采用dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])
,另外一种情况是装不下了,那么直接等于dp[i][j]=dp[i-1][j]
;初始化:如果j=0
,那么dp[i][0]=0
是肯定的,另外一个问题,如果说i=1
那么dp[0][j]=value[0]
。遍历顺序:我感觉这里值得好好思考!
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n,bagweight;//n表示能选择的空间,bagweight表示可用的空间
void solve()
{
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];
}
//将整个dp数组初始化为0
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;
}
int main()
{
while(cin>>n>>bagweight)
{
solve();
}
return 0;
}
一维dp数组解决二维问题,滚动数组:
// 一维dp数组实现
#include <iostream>
#include <vector>
using namespace std;
int main() {
// 读取 M 和 N
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];
}
// 创建一个动态规划数组dp,初始值为0
vector<int> dp(N + 1, 0);
// 外层循环遍历每个类型的研究材料
for (int i = 0; i < M; ++i) {
// 内层循环从 N 空间逐渐减少到当前研究材料所占空间
for (int j = N; j >= costs[i]; --j) {
// 考虑当前研究材料选择和不选择的情况,选择最大值
dp[j] = max(dp[j], dp[j - costs[i]] + values[i]);
}
}
// 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值
cout << dp[N] << endl;
return 0;
}
416.分割等和子集
思路:
class Solution {
public:
bool canPartition(vector<int>& nums) {
vector<int> dp(10001,0);
int sum=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=1;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;
}
};
今日总结:
背包问题,还得总结,有点难度的!