[KCOJ20170214]又一个背包
题目描述 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]又一个背包的更多相关文章
- NGUI实现一个背包功能
界面布局是这样的,一个400*400的背景,然后在其上是16张小图片,每个小图片格子可以用来放置拾取的物品.有两个预制体,一个是可放置的小格子,一个是拾取的物品(包含一个此物品有多少的Label). ...
- dd 在度娘上看到的一个大牛的《背包九讲》 (:
P01: 01背包问题 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本思路 这是最 ...
- POJ 1015 Jury Compromise 2个月后重做,其实这是背包题目
http://poj.org/problem?id=1015 题目大意:在遥远的国家佛罗布尼亚,嫌犯是否有罪,须由陪审团决定.陪审团是由法官从公众中挑选的.先随机挑选n个人作为陪审团的候选人,然后再从 ...
- 背包九讲 && 题目
★.背包求方案数的时候,多重背包是不行的,因为产生重复的背包会有多种情况. ★.背包记录路径的时候,其实是不行的,因为更新了12的最优解,如果它依赖于6这个背包,然后你后面改变了6这个背包,就GG 1 ...
- hdu 5534 (完全背包) Partial Tree
题目:这里 题意: 感觉并不能表达清楚题意,所以 Problem Description In mathematics, and more specifically in graph theory, ...
- A 浪哥的烦恼 完全背包dp
https://biancheng.love/contest-ng/index.html#/131/problems 首先,去到n点的最小时间是所有数加起来. 然后,如果我1 --- 2,然后再2-- ...
- hdu 2955 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=2955 如果认为:1-P是背包的容量,n是物品的个数,sum是所有物品的总价值,条件就是装入背包的物品的体积和不能 ...
- 二维背包(钟神想要的)(不是DP)
[问题描述] 背包是个好东西,希望我也有.给你一个二维的背包,它的体积是? × ?.现在你有一些大小为1× 2和1×3的物品,每个物品有自己的价值.你希望往背包里面装一些物品,使得它们的价值和最大,问 ...
- 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 ...
随机推荐
- activiti在线画流程图
springboot2.2 activiti6.0 activiti-modeler 5.22.0 注明:版本不一样会导致报错 上一篇:springboot整合activiti 效果图 代码分享:ht ...
- postman使用的时候注意的坑
https://cloud.tencent.com/developer/article/1341037
- django实战(三)--删除和批量删除
上一节我们完成了带分页的模糊查询,本节我们继续删除操作. 同样的,先给出各个模块的代码(上一节的就不在贴出了):urls.py path('curd/delete/',views.curd_delet ...
- HTML连载28-标签的权重
一.什么是优先级的权重 1.作用:当多个选择器混合在一起的时候,我们可以通过计算权重来判断谁的优先级最高. 2.权重的计算规则 公共代码: <body> <div id=" ...
- I/O多路复用-EPOLL探索
什么是I/O多路复用 I/O多路复用就是通过一种机制,可以监视多个描述符,一旦某个IO能够读写,通知程序进行相应的读写操作. I/O多路复用的场合 1.当客户处理多个描述字时(通常是交互式输入和网络套 ...
- Unity Shader 2D水流效果
水流的模拟主要运用了顶点变换和纹理动画的结合: 顶点变换中,利用正弦函数模拟河流的大致形态,例如波长,振幅等. 纹理动画中,将纹理坐标朝某一方向持续滚动以形成流动的效果. 脚本如下: Shader & ...
- CountdownLatch例子
CountdownLatch 一个线程或者多个线程等待其他线程完成了再接着往下执行 public class CountDownLatchTest { ); private static Random ...
- c、c++ char*和wchar*互相转换
1. 问题描述 编写程序时通常会面对一些不同的编码格式,如Unicode和multibytes.在有关字符串的处理时尤其重要,系统编程时通常会遇到很多这样的问题,例如把wchar*的字符串转换为cha ...
- 【java】Execption的 e.getMessage()为null的解决方法
================================ 场景: 当代码出现异常时通常都需要将异常信息写入到日志中,异常信息越详细越有利于问题的排查.而通过的Exception.getMess ...
- 数据库系列(五)之 mysql的伸缩性
这篇文章,主要讲述mysql的伸缩性.在国内mysql一直都是使用得最多的数据库,在国外也排名前三.mysql是一款开源的.性能较高的数据库. 伸缩性是指在软件设计中,软件(数据库.应用程序)通过特定 ...