题目描述 Description
小W要去军训了!由于军训基地是封闭的,小W在军训期间将无法离开军训基地。所以他没有办法出去买他最爱吃的零食。万般无奈的小W只好事先买好他爱吃的零食,装在背包里带入军训基地。市场里的零食琳琅满目,纵然小W想把他们都带走,然而小W的背包只有有限的容量。带哪些零食好呢?小W给每种零食都评估了一个他的喜爱程度。另外,由于市场的零食都是散称售卖的,所以一种零食可以只买一部分带走。现在小W希望能挑选出最合适的购买方案,使得所购买的零食能装进背包且喜爱程度总分最大。因为零食的种类实在是太多了,所以小W找到了聪明的你,希望你能尽快(军训的车队即将出发,时间紧迫)告诉他购买方案。
输入描述 Input Description

第一行两个整数n和w,分别表示有n种零食种类和背包总容量。 接下来n行,每行两个整数ci和vi,分别表示第i种食品占的体积和小W的喜爱程度。

输出描述 Output Description
一行一个数字,表示最优购买方案下,所能获得的最大喜爱程度总和。保留3位小数。
样例输入 Sample Input
5 5
1 5
2 4
3 3
4 2
5 1
样例输出 Sample Output
11.000
数据范围及提示 Data Size & Hint
n <= 2000000,w <= 2*10^9,0<=ci <= 100,0<=vi<=100

一道部分背包问题。这道题按性价比排序然后贪心取肯定是没有问题的,但是复杂度是O(n log n)有点大,像我们学校OJ对于n=2000000的肯定是跑不下来的。所以我们要O(n)做这道题。乍一想,发现完全没有思路,应该有一点灵感就是类似于O(n)求第K大数一样,一个用的是O(n log n)排序,一个是nth_element O(n)做的。于是我们就想分治做这道题,把问题分为更小的子问题。算出每个物品的性价比之后,我们nth_element求出中位数,这样这个数列的左边就变成比中位数小的,右边就变成比中位数大的。然后我们暴力扫一遍右边的价值和,判断一下,然后就好办了。复杂度分析的话,这个东西1+1/2+1/4+1/8+...+1/2^n是小于2的,所以类似的话,复杂度就是O(n)。本题还有一个坑点,就是空间有可能是0!

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
using namespace std;
typedef long long LL;
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
const int maxn=;
struct Item
{
double w,v,s;
bool operator < (const Item &t)const {return s<t.s;}
}a[maxn];
int n,ans;
double V;
double solve(int l,int r,double val)//val是当前背包容量
{
if(l>r)return ;
if(l==r)
{
if(val<a[l].v)return val*a[l].s;
else return a[l].w;
}
int mid=(l+r)/;
double sum=,sum2=;
nth_element(a+l,a+mid,a+r+);
for(int i=mid+;i<=r;i++)sum+=a[i].w,sum2+=a[i].v;
//printf("%d %d %d %lf %lf %lf\n",l,r,mid,sum,sum2,val);
if(val>sum2)return sum+solve(l,mid,val-sum2);
if(val==sum2)return sum;
if(val<sum2)return solve(mid+,r,val);
}
int main()
{
n=read();V=(double)read();
int i=;
while(i<=n)
{
a[i].v=(double)read();a[i].w=(double)read();
if(a[i].v==)ans+=a[i].w,n--;
else a[i].s=a[i].w/a[i].v,i++;
}
printf("%.3f\n",ans+solve(,n,V));
return ;
}

[KCOJ20170214]又一个背包的更多相关文章

  1. NGUI实现一个背包功能

    界面布局是这样的,一个400*400的背景,然后在其上是16张小图片,每个小图片格子可以用来放置拾取的物品.有两个预制体,一个是可放置的小格子,一个是拾取的物品(包含一个此物品有多少的Label). ...

  2. dd 在度娘上看到的一个大牛的《背包九讲》 (:

    P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...

  3. POJ 1015 Jury Compromise 2个月后重做,其实这是背包题目

    http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从 ...

  4. 背包九讲 && 题目

    ★.背包求方案数的时候,多重背包是不行的,因为产生重复的背包会有多种情况. ★.背包记录路径的时候,其实是不行的,因为更新了12的最优解,如果它依赖于6这个背包,然后你后面改变了6这个背包,就GG 1 ...

  5. hdu 5534 (完全背包) Partial Tree

    题目:这里 题意: 感觉并不能表达清楚题意,所以 Problem Description In mathematics, and more specifically in graph theory, ...

  6. A 浪哥的烦恼 完全背包dp

    https://biancheng.love/contest-ng/index.html#/131/problems 首先,去到n点的最小时间是所有数加起来. 然后,如果我1 --- 2,然后再2-- ...

  7. hdu 2955 01背包

    http://acm.hdu.edu.cn/showproblem.php?pid=2955 如果认为:1-P是背包的容量,n是物品的个数,sum是所有物品的总价值,条件就是装入背包的物品的体积和不能 ...

  8. 二维背包(钟神想要的)(不是DP)

    [问题描述] 背包是个好东西,希望我也有.给你一个二维的背包,它的体积是? × ?.现在你有一些大小为1× 2和1×3的物品,每个物品有自己的价值.你希望往背包里面装一些物品,使得它们的价值和最大,问 ...

  9. hdu 1561 The more, The Better 背包型树形DP 简单题

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. BS项目启动任意EXE文件或者CS项目

    1. 基于注册表启动exe程序 1. 桌面新建注册表执行文件:protocal.reg 2. 任意文本编辑器打开该文件 Windows Registry Editor Version 5.00 [HK ...

  2. Scala 准引用 - Quasiquote介绍

    Quasiquotes are a neat notation that lets you manipulate Scala syntax trees with ease: scala> val ...

  3. Spring Cloud Feign高级应用

    1.使用feign进行服务间的调用 spring boot2X整合nacos一使用Feign实现服务调用 2.开启gzip压缩 Feign支持对请求与响应的压缩,以提高通信效率,需要在服务消费者配置文 ...

  4. pipeline 多个参数如何传入

    1.准备一个json文件 {    "NAME" : "Lucy",    ",    ",    "ADDRESS" ...

  5. LeetCode 118:杨辉三角 II Pascal's Triangle II

    公众号:爱写bug(ID:icodebugs) 作者:爱写bug 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行. Given a non-negative index k whe ...

  6. centos下java环境搭建安装

    1. 购买服务器(阿里云) 2. 重置密码,重启服务器 3. 创建账号work groupadd work #创建组 mkdir /data # 创建数据文件夹 useradd -d /data/wo ...

  7. git 用 diff 来检查改动

    用 diff 来检查改动 项目的开发是由无数个微小的改动组成的.了解项目开发过程的关键就是要搞清楚每一个改动.当然你可以使用 “git status” 命令或更简单的 “git log” 命令来打印出 ...

  8. Redis(序)应用场景

    前言 在阅读了<大型网站技术架构:核心原理与案例分析>书后,稍微了解了Redis在大型网站架构中的应用场景和目的. 大型网站都是从小用户量,小流量的网站演变过来的,在小型网站的架构之初,L ...

  9. (原创)使用C#开发高性能PLC上位机监控系统服务器应用程序

    PLC服务器监控系统的特点: 1·使用微软C#面向对象开发语言开发应用程序.2·使用了健壮性与性能良好的SUPER SOCKET服务器通信框架,实现自定义应用层通信协议,支持多台PC客户端访问服务器, ...

  10. Spring Cloud Gateway转发Spring WebSocket

    Spring Cloud Gateway转发Spring WebSocket 源码:https://github.com/naah69/SpringCloud-Gateway-WebSocket-De ...