1.
现有4个背包,已知每个物品的体积和价值,每个背包最多容纳10个体积的物品,每件物品只能拿一次,问怎么样装使背包的价值最大?
分析:
(1)二维数组求法:
如果包的体积由0变化到10,每次物品只能放一次,则包内所放物品的价值量为:
则包所放的最大价值即二维数组的最后一个值;
代码如下:
#include <iostream>
using namespace std;
#define N 4//为背包的个数
struct {
int v;
int w;
}b[N+1];
void Read ()
{
int i;
cout<<"请输入每个物品的体积极其价值:"<<endl;
for(i=1;i<=N;i++)
{
cin>>b[i].v;
cin>>b[i].w;
}
cout<<"…………已经读入了物品的体积与价值…………"<<endl;
}
int max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
void function()
{
Read();
int M=0;//为价值量初始值为0;
int a[5][11]={0};//将二维数组优化为一位数组
int i,j;
cout<<"输出物品的体积与价值:"<<endl;
for(i=1;i<=N;i++)
{
cout<<b[i].v<<" ";
cout<<b[i].w;
cout<<endl;
}
for(i=1;i<=N ;i++)
{
for(j=1;j<b[i].v;j++)
a[i][j]=a[i-1][j];
for(j=b[i].v;j<=10;j++)
a[i][j]=max(a[i-1][j],a[i-1][j-b[i].v]+b[i].w);
}//求的是每一行是如何分配的,最大体积时所选择得到的价值是最大价值
cout<<"输出数组中的值"<<endl;// a[j-b[i].v]是指释放掉b[i].v大的空间放b[i].w的价值
for(i=0;i<=4;i++)
{
for(j=0;j<=10;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
cout<<endl;
cout<<"最大值为:"<<endl;
cout<<a[4][10]<<endl;
}
int main()
{
function();
return 0;
}
运行结果为:
(2)
优化为一维数组:
分析:将二维数组变为一维数组,即在上面二维数组的每一行的基础上计算下一行的价值,则最后一行的数据的最后一个值为最大价值;
代码如下:
#include <iostream>
using namespace std;
#define N 4//为背包的个数
struct {
int v;
int w;
}b[N+1];
void Read ()
{
int i;
cout<<"请输入每个物品的体积极其价值:"<<endl;
for(i=1;i<=N;i++)
{
cin>>b[i].v;
cin>>b[i].w;
}
cout<<"…………已经读入了物品的体积与价值…………"<<endl;
}
int max(int a,int b)
{
if(a>b)
return a;
else
return b;
}
void function()
{
Read();
int M=0;//为价值量初始值为0;
int a[11]={0};//将二维数组优化为一位数组
int i,j;
cout<<"输出物品的体积与价值:"<<endl;
for(i=1;i<=N;i++)
{
cout<<b[i].v<<" ";
cout<<b[i].w;
cout<<endl;
}
for(i=1;i<=N ;i++)
for(j=10;j>=b[i].v;j--)
a[j]=max(a[j],a[j-b[i].v]+b[i].w);//求的是每一行是如何分配的,最大体积时所选择得到的价值是最大价值
cout<<"输出数组中的值"<<endl;// a[j-b[i].v]是指释放掉b[i].v大的空间放b[i].w的价值
for(i=0;i<=10;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
cout<<"最大值为:"<<endl;
cout<<a[10]<<endl;
}
int main()
{
function();
return 0;
}
运行结果如下:
该题还可以用递归方法来解决;