ACM复习(35)9513 防空洞
2018-03-10 22:54
399 查看
Description
有一天,dragon123偷偷地拿锄头在学校里挖开了一个尘封已久的防空洞。
他在这个防空洞里面找到许多贵重的东西:一些石头和一些液体。
dragon123知道,只要他把这些石头和液体拿出去卖,那么就一定可以赚大钱。但是,他只有一个载重量为W的瓶子来装这些东西。
防空洞里面有很多块石头,每块石头的重量为Wi,价值为Mi,但是石头不能够砸烂,否则就不值钱了。
此外,洞里面很多种贵重的液体。对于某种液体,洞内存储了Wi重量,且这Wi重量液体的总价值为Mi。
液体是可以部分放进瓶子里面的。也就是说,如果洞里面有Wi重量的某种液体,那么dragon123可以带走Ws(0<=Ws<=Wi)重量。
给出洞里面石头和液体的信息,以及瓶子的载重量W,dragon123希望你帮忙计算出他能够带回东西的最大价值。
输入格式
输入文件的第一行是n与W。
n是洞里面贵重物品的数量总和(包括石头与液体)。W是瓶子的载重量。N (1 <= N <= 100) 且 W (0 <= W <= 50000)
接下来有n行,每行都有3个数字a,b,c。
如果c是0,那么就意味着这一行表示的物品是石头。那么a就是这块石头的重量,b就是这块石头的价值。
如果c是1,那么就意味着这一行表示的物品是液体。那么a就是这种液体在山洞中的总储量,b就是山洞中所有的这种液体的总价值。
输出格式
输出仅有一行,表示能够获得的最大价值。保留小数点后两位小数。
输入样例
3 150
100 100 0
100 100 0
130 10 1
输出样例
103.85
液体:
储量大于瓶子容量:当成完全背包处理
储量小于等于瓶子容量:完全背包转换为01背包
背包九讲
有一天,dragon123偷偷地拿锄头在学校里挖开了一个尘封已久的防空洞。
他在这个防空洞里面找到许多贵重的东西:一些石头和一些液体。
dragon123知道,只要他把这些石头和液体拿出去卖,那么就一定可以赚大钱。但是,他只有一个载重量为W的瓶子来装这些东西。
防空洞里面有很多块石头,每块石头的重量为Wi,价值为Mi,但是石头不能够砸烂,否则就不值钱了。
此外,洞里面很多种贵重的液体。对于某种液体,洞内存储了Wi重量,且这Wi重量液体的总价值为Mi。
液体是可以部分放进瓶子里面的。也就是说,如果洞里面有Wi重量的某种液体,那么dragon123可以带走Ws(0<=Ws<=Wi)重量。
给出洞里面石头和液体的信息,以及瓶子的载重量W,dragon123希望你帮忙计算出他能够带回东西的最大价值。
输入格式
输入文件的第一行是n与W。
n是洞里面贵重物品的数量总和(包括石头与液体)。W是瓶子的载重量。N (1 <= N <= 100) 且 W (0 <= W <= 50000)
接下来有n行,每行都有3个数字a,b,c。
如果c是0,那么就意味着这一行表示的物品是石头。那么a就是这块石头的重量,b就是这块石头的价值。
如果c是1,那么就意味着这一行表示的物品是液体。那么a就是这种液体在山洞中的总储量,b就是山洞中所有的这种液体的总价值。
输出格式
输出仅有一行,表示能够获得的最大价值。保留小数点后两位小数。
输入样例
3 150
100 100 0
100 100 0
130 10 1
输出样例
103.85
解题思路
石头:当成01背包处理液体:
储量大于瓶子容量:当成完全背包处理
储量小于等于瓶子容量:完全背包转换为01背包
背包九讲
#include<stdio.h> double max(double a, double b){return a > b ? a : b;} void one(double value, double weight); void unlimited(double value); void mul(double value, double weight); int v; double F[50001] = {0}; int main() { int n, flag[101]; double weight[101], value[101]; scanf("%d %d", &n, &v); for(int i = 0; i < n; i ++) scanf("%lf %lf %d", &weight[i], &value[i], &flag[i]); for(int i = 0; i < n; i ++) { if(flag[i]) mul(value[i] / weight[i], weight[i]); else one(value[i], weight[i]); } printf("%.2lf\n", F[v]); return 0; } // 01背包 void one(double value, double weight) { for(int i = v; i >= weight; i --) F[i] = max(F[(int)(i - weight)] + value, F[i]); } // 完全背包 void unlimited(double value) { for(int i = 1; i <= v; i ++) F[i] = max(F[i - 1] + value, F[i]); } // 完全背包转01背包 void mul(double value, double weight) { if(weight > v) unlimited(value); else { double k = 1.0; while(weight - k > 0.000001) { one(k * value, k); weight -= k; k *= 2; } one(weight * value, weight); } }
相关文章推荐
- 【35】复习下Vue.js(一个小demo)
- [ACM]hdu 1002 A + B Problem II (复习大数相加)
- ACM复习(36)9521 射了多少 II
- 35:ASP.NET复习系列- web服务-web服务的创建和使用
- HDOJ HDU 2078 复习时间 ACM 2078 IN HDU
- ACM复习(18)8628 相亲
- ACM复习(24)8623 龙龙
- ACM复习(30)9505 射了多少
- ACM复习(46)10690 分面包
- ACM复习(4)1142 巡逻的士兵
- ACM复习(33)9504 面试
- ACM复习(5)1076 K尾相等数
- acm_35表达式求值
- ACM复习(21)8626 原子量计数
- 2015 acm icpc asia regional changchun 队内 模拟 + 背包复习 +Tire树
- 35、重新复习html与css(1)
- [ACM] hdu 1465 不容易系列之一(错排复习)
- ACM复习(26)8635 气球
- ACM复习(47)11153 kill boss
- [ACM] POJ 1088 滑雪 (记忆化搜索复习)