使用动态规划解决0-1背包问题

使用动态规划方法解决0—1背包问题
数据结构的分析
使用动态规划解决问题,基本都会使用辅助数组c[i][j],数组的意义或者说该数组存放的是什么是我们要弄弄清楚的,也就是说,这个值和他的i和j的关系是什么。在0-1背包问题中c[i][j]所表示的意思就是前i件商品放入到容量为j的购物车中获得的最大价值。所以数组的右下角c[n][w]所表示的就是,选择n件商品放入 到容器的大小为w的所能获得的最大的价值。

当当前物品的大小大于当前剩余容量时,表当前的物品不能放入到购物车中,c[i][j]=c[i-1][j]
否则c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+v[i]
j-w[i]的意思是,减去当前商品的大小后,所剩的容量,c[i-1][j-w[i]]则表示i-1件商品在j-w[i]的容量中所能选择的商品的总价值c[i-1][j-w[i]]+v[i]这条语句的意思是选这当前之间商品后,购物车的最大价值。

构造最优解
C[n][w]就是不超过购物车容量能放入物品的最大值,如果还想知道具体哪些物品被放入到了购物车中,就需要根据c[][]数组逆向回推,使用一组一维数组来表示x[i]=1表示第i间商品被放入到了购物车中
首先从c[n][w]开始,如果c[i][j]<=c[i-1][j],表示第i件商品没有被选择i–,x[i]=0,i—
知道i=1

#include
#include
using namespace std;
#define maxn 1005
#define M 105
int c[M][maxn]; //c[i][j]表示前i个物品放入容量为j购物车获得的最大价值
int W[M],v[M]; //w[i]表示第i个物品的重量,v[i]表示第i个物品的价值
int x[M]; //x[i]表示第i个物品是否放入到购物车中
int main()
{
int i,j,n,w ; //n表示n个物品,w表示是购物车的容量
cout<<“请输入物品的个数n:”;
cin>>n;
cout<<“请输入购物车的容量w:”;
cin>>w;
cout<<“请依次输入每件商品的重量w和价值v,用空格分开:”<<endl;
for( i=1;i<=n;i++)
{
cin>>W[i]>>v[i];
}
for(i=0;i<=n;i++) //初始化第0列为0
{
c[i][0]=0;
}
for(i=0;i<=w;i++) //初始化第0行为0
{
c[0][i]=0;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=w;j++)
{
if(j<W[i]) //当前物品的重量大于购物车的容量,不放入该物品
{
c[i][j]=c[i-1][j];
}
else //否则比较此物品的放与不放是否能是的购物车内的价值最大
{
c[i][j]=c[i-1][j]>(c[i-1][j-W[i]]+v[i])?c[i-1][j]:(c[i-1][j-W[i]]+v[i]);
}
}
}
cout<<“装入到购物车的最大价值为:”<<c[n][w]<<endl;
//逆向构造最优解
j=w;
for(i=n;i>0;i–)
{
if(c[i][j]==c[i-1][j])
{
x[i]=0;
}
else
{
x[i]=1;
j=j-W[i];
}
}
cout<<“装入购物车的物品为:”;
for(i=1;i<=n;i++)
{
if(x[i]==1)
{
cout<<i<<" ";
}
}
cout<<endl;
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值