背包问题是 DP 的一种
题目会告诉你 n 类物品的重量、价值以及数量(多重背包特有)
每个物品可选可不选
要求最大的总价值
以物品的数量为划分,分成01背包、完全背包、多重背包
01背包
物品只有 1 种
二维数组
#include<bits/stdc++.h>
using namespace std;
int n;//物品数量
int m;//背包容量
int w[1000];//重量
int v[1000];//价值
int dp[1000][1000];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(w[i]>j)
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
}
cout<<dp[n][m];
return 0;
}
一维数组
#include<bits/stdc++.h>
using namespace std;
int n;//物品数量
int m;//背包容量
int w[1000];//重量
int v[1000];//价值
int dp[1000];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--)
if(j>=w[i])
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
cout<<dp[m];
return 0;
}
完全背包
物品有无限种
二维数组
#include<bits/stdc++.h>
using namespace std;
int n;//物品数量
int m;//背包容量
int w[1000];//重量
int v[1000];//价值
int dp[1000][1000];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(w[i]>j)
dp[i][j]=dp[i-1][j];
else
dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+v[i]);
}
cout<<dp[n][m];
return 0;
}
一维数组
#include<bits/stdc++.h>
using namespace std;
int n;//物品数量
int m;//背包容量
int w[1000];//重量
int v[1000];//价值
int dp[1000];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i];
for(int i=1;i<=n;i++){
for(int j=w[i];j<=m;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
cout<<dp[m];
return 0;
}
多重背包
物品有有限种
一维数组
#include<bits/stdc++.h>
using namespace std;
int n;//物品数量
int m;//背包容量
int w[1000];//重量
int v[1000];//价值
int s[1000];//数量
int dp[1000];
int main(){
cin>>m>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i]>>s[i];
for(int i=1;i<=n;i++){
for(int j=m;j>=0;j--)
for(int k=1;k<=s[i];k++)
if(j>=w[i]*k)
dp[j]=max(dp[j],dp[j-w[i]*k]+v[i]*k);
}
cout<<dp[m];
return 0;
}