Knapsack problem (FZU_2214,福建省第六届ACM-problemC) 01背包+初始化问题+渐缩问题
2016-02-27 12:28
489 查看
Problem C Knapsack problem
Accept: 83 Submit: 457
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).
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.
For each test case, output the maximum value.
15 1512 42 21 14 101 2
15
题目大意:01背包问题。
解题思路:咋一看是简单地背包问题,不过数据过大,无法开数组。不过注意到价值的数据较小。可以将物品的价值和体积位置调换,dp[j]的含义改变为装价值为j的的物品,至少需要多大的容量。运用背包求解(注意:此处的01背包要求恰好装满),求出最后各个价值所需的最小容量,然后通过与限制B进行比较,求出最大容量。
初始化问题:有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背 包装满。如果是第一种问法,要求恰好装满背包,那么在初始化时除了F[0]为0,其 它F[1..V ]均设为−∞,这样就可以保证最终得到的F[V ]是一种恰好装满背包的 最优解。 如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该 将F[0..V ]全部设为0。
代码如下:
Accept: 83 Submit: 457
Time Limit: 3000 mSec Memory Limit : 32768 KB
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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).
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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.
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Output
For each test case, output the maximum value.
![](http://acm.fzu.edu.cn/image/prodesc.gif)
Sample Input
15 1512 42 21 14 101 2
![](http://acm.fzu.edu.cn/image/prodesc.gif)
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; }
相关文章推荐
- hdu 1203 I NEED A OFFER! 01背包
- poj 1159 Palindrome dp 字符串
- 我该如何向我的朋友解释“01背包”问题?
- 01背包问题
- hdu 2546 饭卡 (01背包)
- hdu 2602 Bone Collector (01背包 )
- hdu 2639 Bone Collector II (01背包,第k优解问题)
- [01背包]NOIP2001 PJ T4 装箱问题
- [01背包]NOIP 2005 PJ T3 采药 + 01背包的空间优化
- 01背包问题
- 01背包详解(ZeroOnePack)
- XX采药
- poj_1837
- 背包问题1:01背包
- hdu1203 — I NEED A OFFER! (01背包)
- hdu2602 — Bone Collector
- hdu1864 — 最大报销额
- hdu2546 — 饭卡 (01背包)
- hdu2955 — Robberies (01背包)
- 01背包 问题 思路 整理