• 背包问题 dp


    = =

    所谓背包问题嘛,就是给你个容量一定的包,给你一些有价值的东西,把东西放入包里价值最大。

    参考来源:http://blog.csdn.net/insistgogo/article/details/8579597

    我们用w[i],v[i]分别表示第i件物品的重量,价值。

    这里我们讨论用动态规划解该问题:

    子问题:va[i][j]表示前i件物品,放到容量为j的包里所得最大值

    状态转移方程:va[i][j]=max(va[i-1][j],va[i-1][j-w[i]])

    因而我们可以很快得到代码:复杂度:O(W*N)

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int N =100;
     7 
     8 int va[N][N];
     9 int weight=5,num=3;
    10 int v[N]={0,5,10,20};
    11 int w[N]={0,3,2,2};
    12 //int f[N];
    13 
    14 void datecal1(int weight,int num)
    15 {
    16     for(int j=1;j<=weight;j++)
    17     {
    18         for(int i=1;i<=num;i++)
    19         {
    20             if(w[i]>j)
    21                 va[i][j]=va[i-1][j];
    22             else
    23                 va[i][j]=max(va[i-1][j-w[i]]+v[i],va[i-1][j]);
    24         }
    25     }
    26 }
    27 
    28 void datecal2(int weight,int mum)
    29 {
    30     for(int i=1;i<=num;i++)
    31     {
    32         for(int j=1;j<=weight;j++)
    33         {
    34             if(w[i]>j)
    35                 va[i][j]=va[i-1][j];
    36             else
    37                 va[i][j]=max(va[i-1][j],va[i-1][j-w[i]]+v[i]);
    38         }
    39     }
    40 }
    41 
    42 void showva()
    43 {
    44     for(int i=0;i<=num;i++)
    45     {
    46         for(int j=0;j<=weight;j++)
    47         {
    48             cout<<va[i][j]<<"  ";
    49         }
    50         cout<<endl;
    51     }
    52 }
    53 
    54 int main()
    55 {
    56     memset(va,0,sizeof(va));
    57     datecal1(weight,num);
    58     showva();
    59     cout<<endl;
    60     memset(va,0,sizeof(va));
    61     datecal2(weight,num);
    62     showva();
    63     return 0;
    64 }

    关于两个函数,我测试了一下,结果是一样的,因为va[i][j]所代表的值是一样的

    下面优化了一下储存状态的数组:

    即 将状态转移方程改为:f[j]=max(f[j],f[j-w[i]]+w[i])

    我们用一维数组储存了价值,而且是用逆序枚举的容量,关于为什么,可以看一下原博客

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int N =100;
     7 
     8 int weight=5,num=3;
     9 int v[N]={0,5,10,20};
    10 int w[N]={0,3,2,2};
    11 int f[N];
    12 
    13 void datecal3(int weight,int num)
    14 {
    15     for(int i=1;i<=num;i++)
    16     {
    17         for(int j=weight;j>=w[i];j--)
    18         {
    19             f[j]=max(f[j],f[j-w[i]]+v[i]);
    20         }
    21     }
    22     cout<<f[weight]<<endl;
    23 }

    即我们使用一维数组储存前一个数组的状态,但缺点和最大子序和里面sum替换数组s[]一样,缺失了之前的状态的最大和,仅仅得到了最终结果

    以上是现在学习的0-1背包问题,关于其他背包问题我会在后面继续学习了再完成该博,先搁置一下 

                                                    2016.4.26

  • 相关阅读:
    Windows Server 2003 NLB负载均衡(集群)配置详解
    SQL Server 数据库中关于死锁的分析
    SQL Server 性能调优(一)——从等待状态判断系统资源瓶颈
    RSync实现文件备份同步
    C# 中的委托和事件
    图解用WAS对Web服务器进行压力测试(was下载)
    Windows 之间用rsync同步数据(cwRsyncServer配置)
    SQLServer2005在复制功能中创建发布订阅
    【总结】C# 线程同步技术(一)之 Join 方法
    也来说说C#异步委托
  • 原文地址:https://www.cnblogs.com/byzsxloli/p/5436150.html
Copyright © 2020-2023  润新知