FOJ 2214 Knapsack problem 第六届福建省大学生程序设计竞赛 C 01背包DP变种

来源:互联网 发布:淘宝哪里申请换货 编辑:程序博客网 时间:2024/04/29 08:15

Knapsack problem
Accept: 202    Submit: 817
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


1
5 15
12 4
2 2
1 1
4 10
1 2
 Sample Output


15
 Source


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


题意:01背包,但是背包重量非常大。

思路:不能用传统的公式,题目限制价值总和小于5000,所以可以用价值来dp。dp[i]代表价值总和不大于i的重量的最小值

dp[j] = min(dp[j],dp[j-val[i]]+w[i]);




#include <iostream>#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string>#include <string.h>#include <algorithm>#include <vector>#include <queue>#include <iomanip>#include <time.h>#include <set>#include <map>#include <stack>using namespace std;typedef long long LL;const int INF=0x7fffffff;const int MAX_N=10000;const long long BIG=0x3fffffffffffffff;int val[5005];long long w[509];long long dp[5009];//价值不大于i的重量的最小值int T,n,b;int main(){    cin>>T;    while(T--){        cin>>n>>b;        for(int i=0;i<n;i++){            scanf("%I64d%d",&w[i],&val[i]);        }        fill(dp,dp+5001,BIG);        dp[0]=0;        for(int i = 0;i<n;i++){            for(int j = 5000;j>=val[i];j--){                dp[j] = min(dp[j],dp[j-val[i]]+w[i]);            }        }        long long ans=0;        for(int i=5000;i>=0;i--){           // cout<<dp[i]<<endl;            if(dp[i]<=b){                ans=i;                break;            }        }        cout<<ans<<endl;    }    return 0;}/*15 1512 42 21 14 101 2*/


0 0