0-1背包问题的动规解法


#include<stdio.h>
int a,b,i,j,d,x,k;
#define max(a,b) (a)>(b)? (a):(b)//:这是一个宏定义的运用,见课本160页
#define min(a,b) (a)>(b)? (b):(a)
void search(int i,int c);
int n[10],c[10],w[10][10],p[10][10],m[100][1000];//:n表示物品的个数;c表示背包的容量;w表示物品的质量;p表示物品的价值;m【i】【j】表示有i到n个物品,容量为j的最大价值。
int main()
{
 for(i=0;i<=10;i++)
 {  
  c[i]=1;
  n[i]=1;
 }
 for(i=0;n[i]!=0;i++)
 {
  scanf("%d%d",&n[i],&c[i]);
  for(j=0;j<n[i];j++)
  {
   scanf("%d",&w[i][j]);
  }
  for(k=0;k<n[i];k++)
  {
   scanf("%d",&p[i][k]);
  }
  if(n[i]==0)
  {
   i=i-1;
  }
 }
 d=i;// 记录输入的组数。
 for(i=0;i<d;i++)
 {
  search(i,c[i]);//:寻找最大的价值。
  printf("%d\n",m[1][c[i]]);
 }
printf("0\n");
 return(0);
}
void search(int i,int c)
{
 x=min(w[i][n[i]-1]-1,c);//:先从第n个物品开始,比较背包容量和第n个物品质量大小,逐层向上;这里n[i]减一是因为在上面输入w数组时是从零开始的。
 for(j=0;j<=x;j++)
 {
  m[n[i]][j]=0;//:此时,当w【i】【n【i】】》j时有m[n[i]][j]=0;
 }
 for(j=w[i][n[i]-1];j<=c;j++)
 {
  m[n[i]][j]=p[i][n[i]-1];//:此时,背包可以装下第n个物品,则此时装下即可。
 }
 for(k=n[i]-1;k>1;k--)
 {
  x=min(w[i][k-1]-1,c);
  for(j=0;j<=x;j++)
  {
   m[k][j]=m[k+1][j];//:此时,背包装不下,还等于上一个值。
  }
  for(j=w[i][k];j<=c;j++)
  {
   m[k][j]=max(m[k+1][j],m[k+1][j-w[i][k-1]]+p[i][k-1]);//:此时,背包可以装下该物品,比较背包装下时,和不装时哪个价值大。
  }
 }
 m[1][c]=m[2][c];//:让最后的结果等于上一个的结果,如果最后不能装载下第1个物品,直接输出即可,如果可以,继续进行比较。
 if(c>=w[i][0])
 {
  m[1][c]=max(m[1][c],m[2][c-w[i][0]]+p[i][0]);//:比较和装下第一个物品时,哪个价值大,输出最大值即可。
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值