标签:
问题如下:
设有一个背包可以放入的物品重量为S,现有n件物品,重量分别是w1,w2,w3,…wn。
问能否从这n件物品中选择若干件放入背包中,使得放入的重量之和正好为S。
如果有满足条件的选择,则此背包有解,否则此背包问题无解。(可以理解为一个集合中否存在一个子集使子集和为一定值C)
Input输入数据有多行,包括放入的物品重量为s,物品的件数n,以及每件物品的重量(输入数据均为正整数)
多组测试数据。
Output对于每个测试实例,若满足条件则输出“YES”,若不满足则输出“NO“
Sample Input
20 5
1 3 5 7 9
Sample Output
YES
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= 0
︳false, s< 0
︳false, s> 0 且n< 1
\knap( s, n- 1) 或knap( s- Wn, n- 1) , s> 0 且n>= 1
import java.util.*;
public class Bag {
/**
* @param args
*/
public static boolean knap(int weight, int num) {
if (weight == 0)
return true;
if (weight < 0 || (weight > 0 && num == 0))
return false;
if (knap(weight - date[num - 1], num - 1)) // 拾取date[num-1]物品
{
queue.add(date[num - 1]);
return true;
}
return knap(weight, num - 1);
}
static int[] date = { 1, 2, 3, 4, 5, 6 };
static int count = 0;
static Queue<Integer> queue = new LinkedList<Integer>();
public static void main(String[] args) {
System.out.println(Bag.knap(9, date.length));// 最大重量容量为9,最多有6件物品。
while (!queue.isEmpty())
System.out.println(queue.poll());
}
}
标签:
原文地址:http://www.cnblogs.com/xiaodeyao/p/4510150.html