zoukankan      html  css  js  c++  java
  • 0-1背包问题详解二(完全背包问题)

    问题描述

          给定n种物品和一个背包。物品i的重量是w(i),其价值为v(i),背包的容量为c(即最多能够装c重量的物品)。这n种物品可以重复放置(这是与普通背包问题的不同之处)。普通背包问题

    输入n=5,c=6.物品容量和价值分别为:

                      2   6

                      2   3

                      6    5

                       5   4

                       4    6

    最后输出时:18

    问题求解:

           f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}

                 似乎利用上面那个公式就可以很好的求出解。

          这里给出另外一组公式,该公式和上文的公式是一样的,只是第二个for语句的倒过来。

    for i=1..N
       for v=0..V
           f[v]=max{f[v],f[v-cost]+weight}

     为什么这样一改就可行呢?首先想想为什么上文中要按照v=V..0的逆序来循环。这是因为要保证第i次循环中

    的状态f[i][v]是由状态f[i-1][v-c[i]]递推而来。换句话说,这正是为了保证每件物品只选
    一次,保证在考虑“选入第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品
    的子结果f[i-1][v-c[i]]。而现在完全背包的特点恰是每种物品可选无限件,所以在考
    虑“加选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结果f[i][vc[
    i]],所以就可以并且必须采用v=0..V的顺序循环。这就是这个简单的程序为何成立的
    道理。

     1 void compelteKnapsack(){
     2     int c,n;
     3     cout<<"请输入最大容量,小于100"<<endl;
     4     cin>>c;
     5     cout<<"请输入背包个数"<<endl;
     6     cin>>n;
     7     cout<<"请输入各个背包重量和价值"<<endl;
     8     for(int i=1;i<=n;i++){
     9         cin>>w[i]>>v[i];
    10     }
    11     for(int i=0;i<=n;i++)
    12         p[i]=0;
    13     for(int i=1;i<=n;i++)
    14         for(int j=w[i];j<=c;j++)
    15             p[j]=max(p[j],p[j-w[i]]+v[i]);
    16     cout<<"结果是"<<p[c]<<endl;
    17 }
    View Code

         版权所有,欢迎转载,但是转载请注明出处:潇一

  • 相关阅读:
    CentOS如何查看端口是被哪个应用/进程占用
    VS2010自带的性能分析工具分析.NET程序的性能
    Centos7安装RocketMQ及配置测试
    tbnet编译
    jquery动态生成html代码 怎么 获取id 或 class
    jQuery1.9+中删除了live以后的替代方法
    自定义jQuery插件Step by Step
    jQuery插件开发的两种方法及$.fn.extend的详解
    Informix 配置选项
    Informix ConnetionString Pool Size
  • 原文地址:https://www.cnblogs.com/xiaoyi115/p/3178766.html
Copyright © 2011-2022 走看看