• 背包问题


    问题描述:一个背包容量为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、算法举例:列(物品类别) 行(背包容量) 行列交叉得到背包内物品的价值
      0 1 2 3 4 5 6 7 8 9
    0 0 0 3 3 3 3 3 3 3 3
    1 0 0 3 4 4 7 7 7 7 7
    2 0 0 3 4 5 7 8 9 9 12
    3 0 0 3 4 5 7 8 10 11 12
    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、算法举例:
      0 1 2 3 4 5 6 7 8 9
    0 0 0 3 3 6 6 9 9 12 12
    1 0 0 3 4 6 7 9 10 12 13
    2 0 0 3 4 6 7 9 10 12 13
    3 0 0 3 4 6 7 9 10 12 13
    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;
    }
  • 相关阅读:
    A Tour of Go Switch
    A Tour of Go Exercise: Fibonacci closure
    curl的简单使用
    thinkphp自动验证方法的使用
    Forbidden You don't have permission to access / on this server. You don't have permission to access /phpmyadmin/ on this server. 解决办法
    创建、删除文件夹和文件夹里的文件
    图片的copy,从一个目录复制到另一个目录
    如何把内容写入到文件
    读取文件操作
    文件打开操作
  • 原文地址:https://www.cnblogs.com/ourroad/p/3078942.html
Copyright © 2020-2023  润新知