Knapsack problem (FZU_2214,福建省第六届ACM-problemC) 01背包+初始化问题+渐缩问题

Problem C Knapsack problem

Accept: 83    Submit: 457
Time Limit: 3000 mSec    Memory Limit : 32768 KB

 Problem Description

Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the items into a knapsack so that the total weight is less than or equal to a given limit B and the total value is as large as possible. Find the maximum total value. (Note that each item can be only chosen once).

 Input

The first line contains the integer T indicating to the number of test cases.

For each test case, the first line contains the integers n and B.

Following n lines provide the information of each item.

The i-th line contains the weight w[i] and the value v[i] of the i-th item respectively.

1 <= number of test cases <= 100

1 <= n <= 500

1 <= B, w[i] <= 1000000000

1 <= v[1]+v[2]+...+v[n] <= 5000

All the inputs are integers.

 Output

For each test case, output the maximum value.

 Sample Input

15 1512 42 21 14 101 2

 Sample Output

15

题目大意:01背包问题。

解题思路:咋一看是简单地背包问题,不过数据过大,无法开数组。不过注意到价值的数据较小。可以将物品的价值和体积位置调换,dp[j]的含义改变为装价值为j的的物品,至少需要多大的容量。运用背包求解(注意:此处的01背包要求恰好装满),求出最后各个价值所需的最小容量,然后通过与限制B进行比较,求出最大容量。

初始化问题:有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背 包装满。如果是第一种问法,要求恰好装满背包,那么在初始化时除了F[0]为0,其 它F[1..V ]均设为−∞,这样就可以保证最终得到的F[V ]是一种恰好装满背包的 最优解。 如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该 将F[0..V ]全部设为0。 

代码如下:
#include"cstdio"
#include"iostream"
#define MAXN 5000+10
#define INF 1000000000+10
using namespace std;
int dp[MAXN];	//d[i]表示价值为i所需的最小容量 
int weight[MAXN];
int value[MAXN];
int min(int x,int y){
	return x<y?x:y;
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n;
		int b;
		int valsum=0;
		scanf("%d%d",&n,&b);
		for(int i=1;i<=n;i++){
			scanf("%d%d",&weight[i],&value[i]);
			valsum+=value[i];
		} 
		for(int i=1;i<=valsum;i++){
			dp[i]=INF;
		}
		dp[0]=0;
		for(int i=1;i<=n;i++){
			for(int j=valsum;j>=value[i];j--){
				dp[j]=min(dp[j],dp[j-value[i]]+weight[i]);
			}
		}
		int ans=0;
		for(int j=valsum;j>=0;j--){
			if(dp[j]<=b){
				ans=j;
				break;
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}



你可能感兴趣的:(01背包,渐缩问题,反向背包,初始化问题)