一、背包问题
1.1 01背包问题
**特点:**每件物品最多只用于一次
属性包括:最大值(Max)、最小值(Min)、数量
cpp
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m;
int v[N],w[N];
int f[N][N];
int main()
{
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 = 0;j <= m;j ++)
{
f[i][j] = f[i - 1][j];
if(j >= v[i]) f[i][j] = max(f[i][j],f[i - 1][j - v[i]] + w[i]);
}
}
cout<<f[n][m]<<endl;
return 0;
}
1.2 完全背包问题
**特点:**每件物品有无限个
cpp
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1010;
int n,m;
int v[N],w[N];
int f[N][N];
int mian()
{
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 = 0; j <= m;j ++)
for(int k = 0;k * v[i] <= j; k ++)
f[i][j] = max(f[i][j],f[i - 1][j - v[i] * k] + w[i] * k);
cout<<f[n][m]<<endl;
return 0;
}
1.3 多重背包问题
**特点:**每个物品的个数不同
cpp
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 25000,M = 2010;
int n,m;
int v[N],w[N];
int f[N];
int main()
{
cin>>n>>m;
int cnt = 0;
for(int i = 1;i <= n;i ++)
{
int a,b,s;
cin>>a>>b>>s;
int k = 1;
while(k <= s)
{
cnt ++;
v[cnt] = a * k;
w[cnt] = b * k;
s -= k;
k *= 2;
}
if(s > 0)
{
cnt ++;
v[cnt] = a * s;
w[cnt] = b * s;
}
}
n = cnt;
for(int i = 1;i <= n;i ++)
for(int j = m;j >= v[i];j --)
f[j] = max(f[j],f[j - v[i]] + w[i]);
cout<<f[m]<<endl;
return 0;
}
1.4分组背包问题
**特点:**物品有n组,每一组物品中有若干个
cpp
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 110;
int n,m;
int v[N][N],w[N][N],s[N];
int f[N];
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 = m;j >= 0;j --)
for(int k = 0;k < s[i];k ++)
if(v[i][k] <= j)
f[j] = max(f[j],f[j - v[i][k]] + w[i][k]);
cout<<f[m]<<endl;
return 0;
}