• 动态规划0-1背包问题


    0-1背包问题:

    有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

    这个问题用穷举法当然可以做,但是用动态规划所用的时间花销更少。要用一个二维数组存储局部最优值,最后达到总的最优值,可以说是用空间换时间,非常的经典!如果想真正理解动态规划的思想,就把下面的程序的执行过程在自己的脑海中想一遍,结合程序运行结果图好好的思考一下,看看运行结果图里面的二维数组是如何生成的,虽然会花费一些时间,但是理解后对以后的编程是大有裨益的。

    直接贴c++代码:

    //动态规划 本程序是自底向上自左向右更新最优值
    #include<iostream>
    using namespace std;
    int main()
    {    
        int c=10; //总的承重量,好像没有用到,因为j也可以表示
        int m[6][11]={0}; // 第一行与第一列不用,方便编程,表示需要更新的二维数组
        int w[6]={0,2,2,6,5,4}; //多写个0方便编程,物品的重量
        int v[6]={0,6,3,5,4,6}; //物品的价值
        for(int i=5;i>=1;i--)  //循环五次,动态尝试放入五个物品
            for(int j=1;j<=10;j++)
                {
                    if(i==5) //最后一行不依赖其它行更新最优值,因为表示的是第一个放入背包的物品
                        {
                            if(w[5]<=j)
                                {m[i][j]=v[5];}
                        }
                    else{
                        if(w[i]>j) //动态规划核心,此式子选择动态更新局部最优值
                            {
                                m[i][j]=m[i+1][j]; //动态规划核心,此式子选择动态更新局部最优值
                            }
                         else
                            {
                                m[i][j] =m[i+1][j]>m[i+1][j-w[i]]+v[i]?m[i+1][j]:m[i+1][j-w[i]]+v[i]; //动态规划核心,此式子选择动态更新局部最优值,
                                                            //等价于m[i][j]=max{m[i+1][j],m[i+1][j-w[i]]+v[i]}
    } } } cout<<m[1][10]<<endl;//输出最大价值总和,因为本程序是自底向上自左向右更新最优值,所以最大价值总和在第一行第十列(右上角)。 for(int i=1;i<=5;i++) //循环输出更新后的二维数组 for(int j=1;j<=10;j++){ cout<<m[i][j]; cout<<" "; if(j==10) cout<<endl; } return 0; }

    运行效果图以及自底向上自左向右更新后的二维数组如下:最大总价值为15

     至此最大价值我们求出来了是15,还要解决一个问题:有哪些货物是被选进去了呢?这个问题要用回溯法!就是从程序执行末尾开始

    从运行结果图可知:m[1][10]=15>m[1+1][10]=11,物品一选中,剩余重量:15-物品一的重量=10-2=8     

             m[2][8]=9>m[3][8]=6,物品二选中,剩余重量:8-物品二的重量=8-2=6    //注意到没?m[2][8]中的8就是上一步的剩余重量

             m[3][6]=6=m[4][6]=6,物品三没选中,剩余重量:还是6

             m[4][6]=6=m[5][6]=6,物品四没选中,剩余重量:还是6

             m[5][6]!=0,物品五选中 

             综上:所选物品有物品1,2,5总价值为15.

  • 相关阅读:
    Silverlight4实现三维企业网站
    (学)Lazarus 字符串压缩、解压缩
    (原)Oracel 函数返回 Decimal 丢失小数位问题
    (原)如何提高软件运行速度
    (转) ORA01033: ORACLE 正在初始化或关闭
    (学)正在写一个陌生行业的方案,努力ing
    (学)Telerik GridFoot 如何加合计
    (思)爱的路上千万里
    (学)Telerik RadGridView 中Column 数据字段绑定
    写在2011年伊始
  • 原文地址:https://www.cnblogs.com/lcbg/p/6481559.html
Copyright © 2020-2023  润新知