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/               
      *************************************************************************/

  • 相关阅读:
    hdu 5119 Happy Matt Friends
    hdu 5128 The E-pang Palace
    hdu 5131 Song Jiang's rank list
    hdu 5135 Little Zu Chongzhi's Triangles
    hdu 5137 How Many Maos Does the Guanxi Worth
    hdu 5122 K.Bro Sorting
    Human Gene Functions
    Palindrome(最长公共子序列)
    A Simple problem
    Alignment ( 最长上升(下降)子序列 )
  • 原文地址:https://www.cnblogs.com/submarinex/p/2073432.html
Copyright © 2011-2022 走看看