0-1背包和背包问题(C语言实现)——贪心算法应用(3)

问题描述:
          给定n种物品和一个背包。物品i的重量为w[i],其价值为v[i],背包的容量为c。应如何选择装入  背包的物品,使得装入背包中的物品的总价值最大。每种物品最多装入一次。
          
          0-1背包问题:对于要装入背包中的物品,只有两种选择:全部装入或者不装入。
          背包问题:对于要装入背包中的物品,可以选择装入一部分,不一定要全部装入背包中。

算法分析:
         使用贪心策略求解此类问题时,首先要选出最优的度量标准。
         可供选择的度量标准有三种:价值,容量,单位价值(v/w,价值/重量)。
         显然,价值高的物品容量可能太大,容量大的物品价值也可能很低。最优的度量标准是单位价值。

背包问题算法思路:
         1、将各个物品按照单位价值由高到低排序;
         2、取价值最高者放入背包;
         3、计算背包的剩余空间;
         4、重复2-3步,直到背包剩余容量=0或者物品全部装入背包为止(对于0-1背包,终止条件为背包剩余容量无法装入任意一件物品或者物品全部装入背包)。

下面是C语言实现(DEV c++4.9.9.2运行通过)

#include<stdio.h>

void package(int n,float c,float v[],float w[],float x[]);
void package0_1(int n,float c,float v[],float w[],float x[]); 

int main(void)
{
    int n = 3;
    float c = 20;
    float v[] = {24,15,25};
    float w[] = {15,10,18};//已经按照单位价值降序排列
    float *x;
    x = (float*)malloc(sizeof(float)*n); 
    printf("******背包*******\n");
    package(n,c,v,w,x);
    printf("*******0-1背包******\n");
    package0_1(n,c,v,w,x);
    system("PAUSE");

}

/*
*  背包问题 
*  n:物品个数 
*  c:背包容量 
*  v[]:每个物品的价值 
*  w[]:每个物品的重量(这里已经按照单位价值降序排列 ) 
*  x[]:物品是否放入背包(0表示不放,1表示全部放入,0-1放入一部分) 
*/
void package(int n,float c,float v[],float w[],float x[])
{
     int i;
     for(i=0;i<n;i++)
     {
        x[i] = 0;//初始状态,所有物品都没有被放入背包 
     } 
     
     for(i=0;i<n;i++)
     {
       if(w[i] > c)
       {
         break;
       }
       
       x[i] = 1;
       c = c - w[i];
       printf("放入第%d件物品,背包剩余容量%f.\n",(i+1),c);
     }
     
     if(i<=n)//还可以放入一个物品的一部分 
     {
        x[i] = c/w[i]; 
        
        printf("放入第%d件物品的%f部分.背包剩余容量为0.\n",(i+1),w[i]*x[i]);
     }     
}

/*
*  0-1背包问题 
*  n:物品个数 
*  c:背包容量 
*  v[]:每个物品的价值 
*  w[]:每个物品的重量(这里已经按照单位价值降序排列 ) 
*  x[]:物品是否放入背包(0表示不放,1表示全部放入) 
*/
void package0_1(int n,float c,float v[],float w[],float x[])
{
     int i;
     for(i=0;i<n;i++)
     {
        x[i] = 0;//初始状态,所有物品都没有被放入背包 
     } 
     
     for(i=0;i<n;i++)
     {
       if(w[i] > c)
       {
         break;
       }
       
       x[i] = 1;
       c = c - w[i];
       printf("放入第%d件物品,背包剩余容量%f.\n",(i+1),c);
     }
}

 

虽然背包问题和0-1背包都具有最优子结构性质,但是背包问题用贪心算法求出来的是最优解,0-1背包问题通过贪心算法得不到最优解,因为无法保证最后能将背包装满,部分闲置的背包空间使总价值降低了。


  • 12
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值