zoukankan      html  css  js  c++  java
  • 0/1背包问题简析备忘

    主要就是参照百度百科来的,本文目的是自己学习备忘。

    问题描述:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
    测试数据:
    1
    物品数 5, 背包容量 100, 重量及价格
    77 92   22 22   29 87   50 46   99 90

    2
    物品数 8, 背包容量 200, 重量及价格 
    79 83   58 14   86 54   11 79   28 72   62 52   15 48   68 62 


    解法1,dp方法(同时打印出选了哪些物品1表示选,0表示不选):

    #include <stdio.h>

    #define N 5

    #define V 100

    #if 0

    int c[V + 1] = {0, 15, 10, 35, 18, 25 };//volume = 45

    int w[V + 1] = {0, 20, 15, 30, 25, 23 };

    #else

    int c[V + 1] = {0, 77, 22, 29, 50, 99 };//volume = 100

    int w[V + 1] = {0, 92, 22, 87, 46, 90 };

    #endif

    int f[N][V + 1];

    int flag[N + 1];

    void trace_back ()

    {

    int i = 1;

    int v = V;

    for (i = N; i > 0; --i)

    {

    if (f[i][v] != f[i-1][v])

    {

    v -= c[i];

    flag[i] = 1;

    }

    }

    for (i = 1; i <= N; i++)

    printf ("%d", flag[i]);

    printf ("\n");

    }

    int main(int argc, char * argv[])

    {

    int i = 1;

    int v = 0;

    for (i = 1; i < N; ++i)

    {

    for (v = V; v > 0; --v) 

    {

    if (v >= c[i])

    f[i][v] = (f[i-1][v] > f[i-1][v-c[i]] + w[i]) ?

    f[i-1][v] : f[i-1][v-c[i]] + w[i];

    else

    f[i][v] = f[i-1][v];

    }

    }

    f[N][V] = f[i-1][V] > f[i-1][V-c[i]] + w[i] ? 

    f[i-1][V] : f[i-1][V-c[i]] + w[i];

    printf ("Max value : %d\n", f[N][V]);

    trace_back ();

    return 0;

    }

    以上算法,空间上可以优化,既f可以用一维数组,循环部分改为如下就可以了:

    //注意其中内层循环v必须是递减的,以保证后面用的f[v-c[i]]时用的是i-1状态时存下的值。

    for (i = 1; i < N; ++i)

    {

    for (v = V; v >= c[i]; --v)

    {

    f[v] = f[v] > f[v - c[i]] + w[i] ? 

    f[v] : f[v - c[i]] + w[i];

    }

    f[V] = f[V] > f[V - c[i]] + w[i] ? 

      f[V] : f[V - c[i]] + w[i];

    printf ("Max value : %d\n", f[V]);

    递归解法如下:
    #include <stdio.h>
    #define N 5
    #define V 100
    #define MAXSIZE 10
    #if 0 
    int c[MAXSIZE + 1] = { 15, 10, 35, 18, 25 };//volume = 45
    int w[MAXSIZE + 1] = { 20, 15, 30, 25, 23 };
    #else
    int c[N] = { 77, 22, 29, 50, 99 };//volume = 100
    int w[N] = { 92, 22, 87, 46, 90 };
    #endif
    int F (int n, int v)
    {
    int temp1 = 0;
    int temp2 = 0;
    if (n == 0)
    return 0;
    if ( v >= c[n-1])
    temp1 = F (n - 1, v - c[n-1]) + w[n-1];
    temp2 = F (n - 1, v);
    return temp1 > temp2 ? temp1 : temp2;
    }
    int main (int argc, char *argv[])
    {
    printf ("%d\n", F (N, V));
    return 0;
    }
    时间和空间上都稍优一点,可见递归并不是低效的代名词。

  • 相关阅读:
    9.类与对象二----重载、值传递、可变个数形参
    1.数据库相关概念
    8.类与对象一举例
    7.类与对象一
    Educational Codeforces Round 91 (Rated for Div. 2) B. Universal Solution(思维)
    VS Code配置C++环境: Unable to start debugging. Unexpected GDB output from command报错
    Codeforces Round #655 (Div. 2) C. Omkar and Baseball(思维)
    Redis高可用,高性能,高并发
    .Net Core 中GC的工作原理
    大数据环境下该如何优雅地设计数据分层
  • 原文地址:https://www.cnblogs.com/liujiahi/p/2196373.html
Copyright © 2011-2022 走看看