zoukankan      html  css  js  c++  java
  • [学习笔记]0-1背包问题

    0-1背包问题

    给定n个物品和一个背包。其中物品i的重量为wi,价值为vi,背包容量为c。

    问该如何选择放入背包的物品,使得背包中物品价值总和最大?

    分析

    问题等价与求集合{x1,x2,...,xn},其中xi {0,1}。使得:

    Σxiwi <= c  && maxΣvixi

    因此可想到递归式

    if (w1<=j):

      max(1,j) = v1

    else:

      max(1,j) = 0

    if (wi<=j):

      max(i,j) = max{max(i-1,j), max(i-1,j-wi)+vi}

    else:

      max(i,j) = max(i-1,j)

    (其中max(i,j)表示背包容量为j,可选物品为1,2,...,i)

    然后就有以下算法

     1 #define MAX(a,b) a>b?a:b
     2 
     3 int backpack(int w[], int v[], int n, int c)
     4 {
     5     int max[n+1][c+1];
     6     for (int j = 0; j <= c; j++) 
     7     {
     8         if (j<w[1]) max[1][j] = 0;
     9         else max[1][j] = w[1];
    10     }
    11     for (int i = 2; i <= n; i++) 
    12     {
    13         for (int j = 0; j <= c; j++)
    14         {
    15             if (j < w[i]) max[i][j] = max[i-1][j];
    16             else max[i][j] = MAX(max[i-1][j], max[i-1][j-w[i]]+v[i]);
    17         }
    18     }
    19     return max[n][c];
    20 }

    但是上述方法只是返回了最大价值,要想构造最优解,可以将backpack函数改为返回max数组,然后利用下述函数构造:

     1 int* OptimalSolution(int **m, int w[], int n, int c)
     2 {
     3     int x[n+1];
     4     for (int i = n; i > 1; i--)
     5     {
     6         if (max[i][c]==max[i-1][c]) x[i] = 0;
     7         else
     8         {
     9             x[i] = 1;
    10             c-=w[i];
    11         }
    12     }
    13     x[1] = max[1][c]?1:0;
    14     return x;
    15 }

    优化

    (书中有一个优化的算法,暂时不想看。。过两天看看。)

  • 相关阅读:
    关于Tomcat的那些事儿(一)
    关于Spring的问题(一)
    关于Spring的@RequestBody的使用
    关于Eclipse切换所有分支
    关于使用BetterIntelliJ激活IntelliJ IDEA
    关于Elasticsearch的问题(一)
    关于Elasticsearch那些事
    关于LRU算法及Java实现
    自定义滚动条
    创建型模式之建造者模式
  • 原文地址:https://www.cnblogs.com/zmj97/p/5432721.html
Copyright © 2011-2022 走看看