zoukankan      html  css  js  c++  java
  • 01背包问题

    今天终于把0-1背包搞懂了,随笔记下。

    关于0-1背包问题的算法,资料上写得再详细不过了。

    阐述下问题:

    有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下重量尽可能大。1≤n≤100,1≤Vi≤C≤10000,1≤Wi≤10^6。

    推导出状态转移方程:

    f[i][j] = max(f[i-1][j], f[i-1][j-Vi]+Wi)

    f[i][j] 表示在放好第 i 个物品,总占用背包体积大小为 j 时,可装下最大质量 f[i][j]。

    如果对于 f[i][j] 和  f[i-1][j-Vi] 的关系不是很清楚,那可以想成 f[i][k+Vi] 和  f[i-1][k] ,k表示放好第i-1个物品后总占用背包体积大小为k (k = j - Vi)。

    以下是一组测试数据,及操作的过程。

    修正:i = 4 的时候,j = 3,4,5 分别对应12,16,22

    题目:POJ3624

    用滚动数组写的代码

    View Code
     1 #include <iostream>
    2 #include <cstdio>
    3
    4 using namespace std;
    5
    6 const int MAXN = 12880;
    7
    8 template <class T>
    9 T Max(T a, T b)
    10 {
    11 return (a > b)?a:b;
    12 }
    13
    14 int main()
    15 {
    16 int N, M, V, W;
    17 int f[MAXN+10];
    18 memset(f, 0, sizeof(f));
    19 scanf("%d%d", &N, &M);
    20 for (int i = 1; i <= N; i++)
    21 {
    22 scanf("%d%d", &V, &W);
    23 for (int j = M; j >= 0; j--)
    24 {
    25 if (j >= V)
    26 {
    27 f[j] = Max(f[j], f[j-V] + W);
    28 }
    29 }
    30 }
    31 printf("%d\n", f[M]);
    32
    33 return 0;
    34 }


    /**************************************************************************
                      原文来自博客园——Submarinex的博客: www.cnblogs.com/submarinex/               
      *************************************************************************/

  • 相关阅读:
    第三套三
    多线程读写共享变量时,synchronized与volatile的作用
    jQuery源代码学习笔记:构造jQuery对象
    写入位置时发生訪问冲突
    Free Editor
    大区间素数筛选 POJ2689
    HDU
    CentOS下挂载U盘
    得到当前堆栈信息的两种方式(Thread和Throwable)的纠结
    [实战]MVC5+EF6+MySql企业网盘实战(9)——编辑文件名
  • 原文地址:https://www.cnblogs.com/submarinex/p/2073432.html
Copyright © 2011-2022 走看看