您的位置:首页 > 其它

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

2016-02-27 12:28 489 查看
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
<= 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息