普通01背包 一维数组解
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int a[1005],w[1005],dp[1005]={};
for(int i=1;i<=n;i++){
cin>>a[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j = m;j>=a[i];j--){
dp[j] = max(dp[j],dp[j-a[i]]+w[i]);
}
}
cout<<dp[m];
}
01背包 二维数组
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int v[MAXN]; // 体积
int w[MAXN]; // 价值
int f[MAXN][MAXN]; // f[i][j], j体积下前i个物品的最大价值
int main() {
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> v[i] >> w[i];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
if(j < v[i])
f[i][j] = f[i - 1][j];
else
f[i][j] = max(f[i - 1][j], f[i - 1][j - v[i]] + w[i]);
}
cout << f[n][m] << endl;
return 0;
}
完全背包 相当于01背包物品无限
完全背包 一维数组
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int a[1005],w[1005],dp[1005]={};
for(int i=1;i<=n;i++){
cin>>a[i]>>w[i];
}
for(int i=1;i<=n;i++){
for(int j = a[i];j<=m;j++){
dp[j] = max(dp[j],dp[j-a[i]]+w[i]);
}
}
cout<<dp[m];
}
完全背包 二维数组
#include<iostream>
using namespace std;
const int N = 1010;
int f[N];
int v[N],w[N];
int main(){
int n,m;
cin>>n>>m;
for(int i = 1 ; i <= n ;i ++){
cin>>v[i]>>w[i];
}
for(int i = 1 ; i<=n ;i++)
for(int j = v[i] ; j<=m ;j++){
f[j] = max(f[j],f[j-v[i]]+w[i]);
}
cout<<f[m]<<endl;
}
多重背包 在01背包基础上 增加物品的个数
多重背包 一维数组
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int a[1005],w[1005],dp[1005]={},g[1005];
for(int i=1;i<=n;i++){
cin>>a[i]>>w[i]>>g[i];
}
for(int i=1;i<=n;i++){
for(int j=m;j>=a[i];j--){
for(int k=1;k<=g[i];k++){
if(j>=a[i]*k)dp[j] = max(dp[j],dp[j-a[i]*k]+w[i]*k);
}
}
}
cout<<dp[m];
}
多重背包 二进制优化
详解请参考这篇文章
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
int a[100005],w[100005],dp[100005]={},g[100005],cnt=0;
for(int i=1;i<=n;i++){
int aa,ww,gg;
cin>>aa>>ww>>gg;
int s = gg;
int k = 1;
while(k<=s){
cnt++;
a[cnt] = aa*k;
w[cnt] = ww*k;
s-=k;
k=k*2;
}
if(s>0){
cnt++;
a[cnt] = aa*s;
w[cnt] = ww*s;
}
}
n=cnt;
for(int i=1;i<=n;i++){
for(int j=m;j>=a[i];j--){
dp[j] = max(dp[j],dp[j-a[i]]+w[i]);
}
}
cout<<dp[m];
}
分组背包相当于01背包分不同组,每组只能拿一个
分组背包 一维数组
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N];
int v[N][N],w[N][N],s[N];
int n,m,k;
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>s[i];
for(int j=0;j<s[i];j++){
cin>>v[i][j]>>w[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=m;j>=0;j--){
for(int k=0;k<s[i];k++){
if(j>=v[i][k]) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
}
}
}
cout<<f[m]<<endl;
}
分组背包 二维数组
#include<bits/stdc++.h>
using namespace std;
const int N=110;
int f[N][N];
int v[N][N],w[N][N],s[N];
int n,m,k;
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>s[i];
for(int j=0;j<s[i];j++){
cin>>v[i][j]>>w[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
f[i][j]=f[i-1][j];
for(int k=0;k<s[i];k++){
if(j>=v[i][k]) f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
}
}
cout<<f[n][m]<<endl;
}