背包问题

问题描述:一个背包容量为V,有N件不同类别的物品体积和价值分别为:v[i], w[i],把这些物品装入背包中保证背包中物品的价值最高。背包问题分为以下几种:
一、0/1背包问题
1、算法描述:背包里的物品不能有重复,属于不同类别;
2、算法方程式:f[i][v] = max{f[i-1][v], f[i-1][v - c[i]] + w[i]};
3、算法举例:列(物品类别) 行(背包容量) 行列交叉得到背包内物品的价值
 0123456789
00033333333
10034477777
200345789912
30034578101112
4、源代码:
#include <stdio.h>
 
static int f[10] = {0};
static const int V = 9;
static const int c[4] = {2, 3, 4, 5};
static const int w[4] = {3, 4, 5, 7};
 
void ZeroOnePack(int cost, int weight)
{
      for(int v = V; v >= cost; -- v)
      {
            f[v] = (f[v] > f[v - cost] + weight) ? f[v] : f[v - cost] + weight;
      }
}
 
int  main( int  argc,  char * argv[])
{
       for ( int  i = 0; i < n; ++ i)
      {
           ZeroOnePack(c[i], w[i]);
      }
      printf( "%d" , f[V]);
       return  0;
}
 
二、完全背包问题
1、算法描述:背包中属于同一类别 的 物品可以重复 ,且每种类别物品数量不限;
2、算法方程式:f[i][v] = max{f[i-1][v], f[i-1][v - k * c[i]] + k * w[i]}(0=<k*c[i]<=V);
3、算法举例:
 0123456789
0003366991212
10034679101213
20034679101213
30034679101213
4、源代码:
#include <stdio.h>
 
static int f[10] = {0};
static const int V = 9;
static const int c[4] = {2, 3, 4, 5};
static const int w[4] = {3, 4, 5, 7};
 
void CompletePack(int cost, int weight)
{
      for(int v = cost; v <= V; ++ v)
      {
            f[v] = (f[v] > f[v - cost] + weight) ? f[v] : f[v - cost] + weight;
      }
}
 
int main(int argc, char* argv[])
{
      for(int i = 0; i < n; ++ i)
      {
            CompletePack(c[i], w[i]);
      }
      printf("%d", f[V]);
      return 0;
}
 
三、多重背包问题
1、算法描述:背 包中属于同一类别 的 物品可以重复 ,但第i种物品数量最大量为n[i];
2、算法方程式:f[i][v]=max{f[i-1][v - k * c[i]] + k * w[i]}(0=<k<=n[i]);
3、源代码:
#include <stdio.h>
 
static int f[10] = {0};
static const int V = 9;
static const int n[4] = {2, 1, 1, 1};
static const int c[4] = {2, 3, 4, 5};
static const int w[4] = {3, 4, 5, 7};
 
//0/1背包解法
void ZeroOnePack(int cost, int weight)
{
      for(int v = V; v >= cost; -- v)
      {
            f[v] = (f[v] > f[v - cost] + weight) ? f[v] : f[v - cost] + weight;
      }
}
 
//完全背包解法
void CompletePack(int cost, int weight)
{
      for(int v = cost; v <= V; ++ v)
      {
            f[v] = (f[v] > f[v - cost] + weight) ? f[v] : f[v - cost] + weight;
      }
}
 
//多重背包解法
void MultiplePack(int cost, int weight, int amount)
{
      if(cost * amount >= V)
      {
            CompletePack(cost, weight);
            return ;
      }
 
      int k = 1;
      while(k < amount)
      {
            ZeroOnePack(k * cost, k * weight);
            amount -= k;
            k *= 2;
      }
 
      ZeroOnePack(amount * cost, amount * weight);
}
 
int main(int argc, char* argv[])
{
      for(int i = 0; i < 4; ++ i)
      {
            MultiplePack(c[i], w[i], n[i]);
      }
 
      printf("%d", f[V]);
      return 0;
}

转载于:https://www.cnblogs.com/ourroad/archive/2011/12/12/3078942.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值