zoukankan      html  css  js  c++  java
  • 递归思想即背包问题

    01背包问题:
    
    
    1.递归思想
    
    0- 1 背包问题如果采用递归算法来描述则非常清楚明白, 它的算法根本思想是假设用布尔函数
    knap( s, n) 表示n 件物品放入可容质量为s 的背包中是否有解( 当knap 函数的值为真时
    
    说明问题有解,其值为假时无解) . 我们可以通过输入s 和n 的值, 根据它们的值可分为以下几种情况讨论:
    
    ( 1) 当s= 0时可知问题有解, 即函数knap( s, n) 的值为true; ( 2) 当s< 0 时这时不可能,
    
    所以函数值为false; ( 3) 当输入的s> 0 且n< 1 时即总物品的件数不足1, 这时函数值为false,
    
    只有s> 0 且n 1 时才符合实际情况,这时又分为两种情况: ( 1) 选择的一组物体中不包括Wn
    
    则knap( s, n) 的解就是knap( s, n- 1) 的解. ( 2) 选择的一组物体中包括Wn 则knap( s, n) 的解
    
    就是knap( s- Wn, n- 1) 的解. 这样一组Wn 的值就是问题的最佳解. 这样就将规模为n 的问题转化为
    
    规模为n- 1 的问题. 综上所述0- 1 背包问题的递归函数定义为:
    knap( s, n) =∕true, s= 0false, s< 0false, s> 0 且n< 1
                  knap( s, n- 1) 或knap( s- Wn, n- 1) , s> 0 且n>= 1
    采用此法求解0- 1 背包问题的时间复杂度为O( n) . 上述算法对于所有物品中的某几件恰能装满背包
    时能准确求出最佳解. 但一般情况是对于某一些物品无论怎么装都不能装满背包, 必须要按背包的最大
    容量来装. 如物品件数为4, 其质量分别为: 10, 2, 5, 4, 背包的容量为20, 则这四件物品无论怎么放都不
    能恰好装满背包, 但应能最大限度装, 即必须装下10, 5, 4 这三件物品, 这样就能得到最大质量19. 对于
    这种装不满的背包它的解决办法是这样的: 按所有物品的组合质量最大的方法装背包, 如果还装不满,
    则我们可以考虑剩余空间能否装下所有物品中最小的那件, 如果连最小的都装不下了则说明这样得到
    的解是最佳解, 问题解决. 这样我们必须先找出所有n 件物品中质量最小的那件( 它的质量为Min) , 但
    是为了问题的解决我们不能增加运算次数太多, 并且必须运用上述递归函数. 那么我们可通过修改s 的
    值即背包的容量, 从背包容量s 中减去k( 它的值是从0 到Min- 1 之间的一个整数值) , 再调用递归函
    数. 当k= 0 时即能装满背包, 其它值也能保证背包能最大限度装满, 这样所有问题都解决了.
    Description 
    设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,…wn。 
    问能否从这n件物品中选择若干件放入背包中,使得放入的重量之和正好为S。 
    如果有满足条件的选择,则此背包有解,否则此背包问题无解。
      
    Input输入数据有多行,包括放入的物品重量为s,物品的件数n,以及每件物品的重量(输入数据均为正整数)
    多组测试数据。 
    Output对于每个测试实例,若满足条件则输出“YES”,若不满足则输出“NO“ 
    Sample Input
    20 5
    1 3 5 7 9
    Sample Output
    YES
    
    复制代码
    # include<stdio.h>
    # include<string.h>
    int date[1005];
    int f(int w,int s)
    {
        if(w==0) return 1;//正好
        if(w<0||w>0 &&s==0) return 0;
        if(f(w-date[s],s-1)) return 1;//退出来再选下一个 
        return f(w,s-1);//选择下一个
    }
    
    int main()
    {
     int i,Weight,n;
     while(scanf("%d %d",&Weight,&n)!=EOF)
     {
         memset(date,0,sizeof(date));
     for(i=1;i<=n;i++)
      scanf("%d",&date[i]);
        if(f(Weight,n))
           printf("YES
    ");
     else printf("NO
    ");
     }
     return 0;
    }
    }
    http://i.cnblogs.com/EditPosts.aspx?opt=1
  • 相关阅读:
    const对象 不能调用非const修饰的成员函数
    Sqlserver 查询 临时字段
    win7 VC6.0 安装 fatal error C1083: Cannot open include file: 'Iphlpapi.h': No such file or directory
    RtlWerpReportException failed with status code :-1073741823
    MFC 去掉CWnd的边框
    阿里云 linux 找回mysql root密码
    IE 内使用ActiveX,写注册表被重定向到如下注册表
    mysqli得到记录数量
    error C4996 The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name
    在MFC主对话框OnInitDialog()中弹出对话框
  • 原文地址:https://www.cnblogs.com/leijiangtao/p/4108056.html
Copyright © 2011-2022 走看看