一、0-1背包
原始0-1背包问题描述:
给定n种物品,以及第i个物品的空间大小a[i]和价值c[i]。有一容量为V背包,问:应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
输入:
一个整数V:背包的容量;
一个整数n:物品的个数;
第i个物品的空间大小a[i];
第i个物品价值c[i];
输出:
背包中物品最大总价值
举例:
输入:
10
3
2 5 4
5 7 10
输出:
17
c++代码实现(动态规划求解):
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,k,l,n,m;
int a[1000],b[1000],c[1000],f[1000];
int fun(int a[], int c[])
{
for(i=1;i<=n;i++) {
for(j=m;j>=a[i];j--) {
if (f[j] < f[j - a[i]] + c[i])
f[j] = f[j - a[i]] + c[i];
}
}
return f[m];
}
int main()
{
/**输入参数:
* @param m 表示背包的最大容量
* @param n 表示商品个数
* @param a[] 每个商品的容量
* @param c[] 每个商品的价值
*/
cin>>m;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>c[i];
/**求最大value函数*/
cout<<fun(a,c)<<endl;
return 0;
}
0-1背包延伸问题1:
描述:
给定n种物品,以及第i个物品的空间大小a[i]。有一容量为V背包,问:应如何选择装入背包的物品,使得装入背包剩余空间最小?
输入:
一个整数V:背包的容量;
一个整数n:物品的个数;
第i个物品的空间大小a[i];
输出:
一个整数:最小剩余空间
举例:
输入:
10
3
2 5 4
输出:
1
分析:
背包型动态规划,相当于背包容量和背包中物品价值二者相等的0-1背包问题。
c++代码实现(动态规划求解):
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,k,l,n,m;
int a[1000],b[1000],f[1000];
int fun(int a[])
{
for(i=1;i<=n;i++) {
for(j=m;j>=a[i];j--) {
if (f[j] < f[j - a[i]] + a[i])
f[j] = f[j - a[i]] + a[i];
}
}
return f[m];
}
int main()
{
/**输入参数:
* @param m 表示背包的最大容量
* @param n 表示商品个数
* @param a[] 每个商品的容量
*/
cin>>m;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
/**求最大value函数*/
cout<<m-fun(a)<<endl;
return 0;
}
0-1背包延伸问题2:
在原始基础上多加了一个限制条件,比如不超过最大质量。
/**
限定条件为两种的背包问题
*/
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,k,l,n,m;
int a[1000],b[1000],c[1000],f[1000][1000];
void fun(int a[], int b[], int c[])
{
for(i=1;i<=n;i++) {
for(j=m;j>=a[i];j--) {
for(l=k;l>=b[i];l--) {
//if(j>=a[i]&&l>=b[i])
f[j][l]=max(f[j][l],f[j-a[i]][l-b[i]]+c[i]);
}
}
}
}
int main()
{
//memset(f,0,sizeof(f));
/**输入参数:
* @param m 表示背包的最大容量
* @param k 表示背包的最大质量
* @param n 表示商品个数
* @param a[] 每个商品的容量
* @param b[] 每个商品的质量
* @param p[] 每个商品的价值
*/
cin>>m>>k;
cin>>n;
//for(i=1;i<=n;i++)cin>>a[i]>>b[i]>>c[i];
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>b[i];
for(i=1;i<=n;i++)
cin>>c[i];
/**求最大value函数*/
fun(a,b,c);
cout<<f[m][k]<<endl;
return 0;
}
二、完全背包
问题描述:
完全背包:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
代码:
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,k,l,n,m;
int a[1000],b[1000],c[1000],f[1000];
int fun(int a[], int c[])
{
for(i=1;i<=n;i++) {
for(j=a[i];j<=m;j++) { //注意此处,与0-1背包不同,这里为顺序,0-1背包为逆序
if (f[j] < f[j - a[i]] + c[i])
f[j] = f[j - a[i]] + c[i];
}
}
return f[m];
}
int main()
{
/**输入参数:
* @param m 表示背包的最大容量
* @param n 表示商品个数
* @param a[] 每个商品的容量
* @param c[] 每个商品的价值
*/
cin>>m;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>c[i];
/**求最大value函数*/
cout<<fun(a,c)<<endl;
return 0;
}
三、多重背包
问题描述:
多重背包:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
思路:转化为0-1背包问题。
代码:
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,n,m,z=1;
int a[1000],p[1000],c[1000],f[1000],a1[1000],c1[1000];
int fun(int a[], int c[])
{
for(i=1;i<=z-1;i++) {
for(j=m;j>=a[i];j--) {
if (f[j] < f[j - a[i]] + c[i])
f[j] = f[j - a[i]] + c[i];
}
}
return f[m];
}
void convt(int a[],int p[], int c[]){
for(i=1;i<=n;i++){
for(j=1;j<=p[i];j++){
a1[z] = a[i];
c1[z] = c[i];
z++;
}
}
}
int main()
{
/**输入参数:
* @param m 表示背包的最大容量
* @param n 表示商品的类数
* @param a[] 每类商品的容量
* @param p[] 每类商品的数量
* @param c[] 每类商品的价值
*/
cin>>m;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>p[i];
for(i=1;i<=n;i++)
cin>>c[i];a
/**转为0-1背包**/
convt(a,p,c);
/**求最大value函数*/
cout<<fun(a1,c1)<<endl;
return 0;
}
或者:
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
int i,j,k,n,m;
int a[1000],p[1000],c[1000],f[1000];
int fun(int a[], int c[]){
for(i=1;i<=n;i++) {
for(j=m;j>=a[i];j--){
for(k=1;k<=p[i];k++){
if(j<k*a[i])break;
f[j] = max(f[j],f[j-k*a[i]]+k*c[i]);
}
}
}
return f[m];
}
int main()
{
/**输入参数:
* @param m 表示背包的最大容量
* @param n 表示商品的类数
* @param a[] 每类商品的容量
* @param p[] 每类商品的数量
* @param c[] 每类商品的价值
*/
cin>>m;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=1;i<=n;i++)
cin>>p[i];
for(i=1;i<=n;i++)
cin>>c[i];
/**求最大value函数*/
cout<<fun(a,c)<<endl;
return 0;
}