• LFYZ-OJ ID: 1028 背包问题


    背包问题

    题目描述

    简单的背包问题。设有一个背包,可以放入的重量为s。现有n件物品,重量分别为w1,w2…,wn,(1≤i≤n)均为正整数,从n件物品中挑选若干件,使得放入背包的重量之和正好为s。找到一组解即可。

    输入

    第一行是物品总件数和背包的载重量,第二行为各物品的重量。

    输出

    各所选物品重量。

    样例输入

    5 10
    1 2 3 4 5

    样例输出

    number:1 weight:1
    number:4 weight:4
    number:5 weight:5

    分析

    • 背包问题是最经典的算法问题之一。当数据量很小时,使用枚举法把所有情况测试一遍即可解决,然而当数据量很大时,这种方法就无可行性,需要使用到二叉树结构和动态规划等进行解决,这在以后的学习中会讲到。在这里因为数据量很小,我们仍然考虑最简单的方法:枚举。

    • 这样枚举:有n件商品,每件商品可以选择装或者不装,那就有2X2X2X...X2=2n种情况。你知道为什么n很大的时候就不能枚举了吧?指数级的时间复杂度时很可怕的!

    • 该如何编程实现上面的枚举方法?这其实也是n个物品的组合问题。这里提供一个递归的思路。函数bool search(int itemNum, int space)有两个参数,第一个参数是物品编号,第二个参数是背包的空间大小。

      • 递归的终止条件1:space<0----->return false;(超重)
      • 递归的终止条件2:space==0---->return true;(刚好装满)
      • 递归的终止条件3:itemNum==0-->return false;(没有物品了)
      • 递归方法
        • search(itemNum-1, space-item[itemNum])装上物品itemNum,尝试装物品itemNum-1
        • search(itemNum-1, space)不装物品itemNum,尝试装物品itemNum-1

    递归过程中itemNum从n递归到1,这是因为输出格式中物品号码小的在前、大的在后,按照递归的顺序,后入栈的先出栈,也就是后装的先输出,所以枚举过程中先枚举编号大的物品,最后枚举编号小的物品,使得输出时先输出编号小的物品。需要注意的是,满足情况的装载情况不只有一种,例程在找到一种方案后即返回,不会把所有的方案找出来。你可以自己尝试一下,把所有的装载情况列举出来!

    例程

    #include<iostream>
    using namespace std;
    int n, item[1000];                                      //item数组存储物品的重量
    int s;
    bool search(int itemNum, int space){
    	if(space==0)					return true;        //终止条件
    	if(space<0 || itemNum==0)		return false;       //终止条件
    	if(search(itemNum-1, space-item[itemNum])){         //装物品itemNum,尝试装物品itemNum-1,成功返回true
    		cout<<"number:"<<itemNum<<"  weight:"<<item[itemNum]<<endl;
    		return true;
    	}
    	if(search(itemNum-1, space)){                       //不装物品itemNum,尝试装物品itemNum-1,成功返回true
    		return true;
    	}
    	return false;
    }
    int main(){
    	cin>>n>>s;
    	for(int i=1; i<=n; i++)	cin>>item[i];
    	if(!search(n, s))                                   //返回false代表没有找到合适的方案
    		cout<<"not found";
    	return 0;
    }
    
  • 相关阅读:
    Redis Java API
    怎样测试TCP&UDP端口
    [转]太阳致敬式瑜伽
    [转]你所不知道的超级瘦腿运动——空中蹬自行车
    Oracle 存储过程学习
    hive Java API
    [转]骨盆操
    [转]HDFS客户端的权限错误:Permission denied
    【转】拇指拇外翻的纠正训练
    [转]shell 变量替换
  • 原文地址:https://www.cnblogs.com/lfyzoi/p/6902939.html
Copyright © 2020-2023  润新知