FZU 2214 ——Knapsack problem——————【01背包的超大背包】

时间:2022-03-04 03:56:53
2214 Knapsack problem

Accept: 6    Submit: 9
Time Limit: 3000 mSec    Memory Limit : 32768 KB

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 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).

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 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.

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 Output

For each test case, output the maximum value.

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 Sample Input

1
5 15
12 4
2 2
1 1
4 10
1 2

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 Sample Output

15

FZU 2214 ——Knapsack problem——————【01背包的超大背包】 Source

第六届福建省大学生程序设计竞赛-重现赛(感谢承办方华侨大学)

 
 
题目大意:给你T组数据,每组有n个物品,一个背包容量B,每件有体积和价值。问你这个背包容纳的物品最大价值是多少。每个物品只能放入一次背包。
 
解题思路:首先这个很清楚看出来是个01背包。但是这个背包容量特别大,同时物品的体积很大,总的价值却很少。寻常意义上dp[i]表示背包容量为i时的最大价值,那么我们把这个dp[]数组的含义改变一下,dp[i]表示装价值为i时所需的最小容量。
 
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 550;
const int INF = 0x3f3f3f3f;
int w[maxn], v[maxn];
int dp[5500];
int main(){
int T, n, B;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&B);
int V = 0;
for(int i = 1; i <= n; i++){
scanf("%d%d",&w[i],&v[i]);
V += v[i];
}
memset(dp,INF,sizeof(dp));
dp[0] = 0;
for(int i = 1; i <= n; i++){
for(int j = V; j >= v[i]; j--){
dp[j] = min(dp[j],dp[j-v[i]]+w[i]);
// printf("%d ",dp[j]);
}
}
int ans = 0;
for(int i = V; i >= 0; i--){
if(dp[i] <= B){
ans = i; break;
}
}
printf("%d\n",ans);
}
return 0;
}