zoukankan      html  css  js  c++  java
  • 0-1背包

    接下来看一个动态规划的经典问题:0-1背包问题  

    问题描述:

       给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
    这个问题确实是要困难一些,首先这个状态就不是很好确定,由于个额外的条件,背包容量有限,所以要兼顾考虑两个因素的限制,一个是选什么物品,一个是总重量不过界。为此我们采用二维数组,利用两个维度的索引值来解决这个问题。
    假设代表重量的数组为W,代表价值的数组为P。
    状态c[ i ][ j ]表示前 i 件物品在重量 j 内的最大总价值,注意这个状态不是很好理解,前 i 件物品可以选可以不选,重量 j 内说明当前状态的总重量并没有超过 j。
    同样这个问题的状态转移方程也不是很好理解,对于c[ i ][ j ],当 j < W【i】时,这个物件装不下,此时c[ i ][ j ]  = c[ i - 1 ][ j ]
    当 j > W【i】时,这个物品能够装下,但是此时有两种情况,第一种仍然是c[ i - 1 ][ j ](可以理解为不装这个物品),第二种情况是c[ i - 1 ][ j - W[ i ] ] + p[ i ](装下这个物品,但是会涉及到前一个状态c[ i - 1 ][ j - W[ i ] ],这个我暂时没办法讲的很清楚,不过这个表达式的确是这样的),此时c[ i ][ j ] 为两者中较大的那个值。
    直接上代码,我直接定义了一种情况:
     1 void main(){
     2 
     3 int weight = 120;
     4     int w[6] = {0,40,50,70,40,20};   
     5     int p[6] = {0,10,25,40,20,10};
     6     int **c = (int**)malloc((6)*sizeof(int*));
     7     for (int i = 0; i <= 5; ++i){
     8         c[i] = (int*)malloc((weight+1)*sizeof(int));
     9     }
    10     int temp1 = 0;
    11     int temp2 = 0;
    12     for (int i = 0; i <= weight; ++i)
    13         c[0][i] = 0;
    14     for (int i = 1; i <= 5; ++i){
    15         c[i][0] = 0;
    16         for (int j = 1; j <= weight; ++j){
    17             if (w[i] > j)c[i][j] = c[i - 1][j];
    18             else{
    19                 temp1 = c[i - 1][j];
    20                 temp2 = c[i - 1][j - w[i]] + p[i];
    21                 c[i][j] = temp1 > temp2 ? temp1 : temp2;
    22             }
    23         }
    24     }
    25         
    26     cout << c[5][120] << endl;
    27 }
  • 相关阅读:
    border-sizing属性详解和应用
    初识scss:配置与运行
    详解scss的继承、占位符和混合宏
    详解promise、async和await的执行顺序
    JS调用模式
    自已写的线程池
    ThreadPool.QueueUserWorkItem的用法
    C#定时执行
    Task.Factory.StartNew的用法
    C#写文本日志帮助类(支持多线程)改进版(不适用于ASP.NET程序)
  • 原文地址:https://www.cnblogs.com/messi2017/p/8025224.html
Copyright © 2011-2022 走看看