题目链接:http://codeforces.com/problemset/problem/808/E

题意:给出n个体积为wi, 价值为ci的物品,背包容量为m,求能容纳的最大物品价值,其中 1<=wi<=3;

思路:看到题目首先想到了atcoder的一道题http://www.cnblogs.com/geloutingyu/p/6789985.html

然而这里的 n 为 1e5,直接贪心枚举肯定是不行的.可以考虑O(nlogn)的算法...

这里可以先按照价值从大到小枚举体积为3的物品,用剩余的容量去装体积为1, 和 2 的物品使剩余空间取得最大值,所有枚举情况中的最大值即为答案;

现在问题转化成了在O(longn)的时间复杂度内求出剩余空间能容纳的1,和2物品最大价值,以物品2的数目为 x 轴,能容纳的最大价值为 y 轴,

将其描点再连成光滑曲线后是一条单峰抛物线 / 单峰拋物线的一侧 ;可以做个简易的证明,对于已经降序排列的物品1, 物品2 显然其单位体积的

价值是非递增的,用 i 表示当前选了 i 个物品2,area2( i )为前 i 个物品平均单位体积的价值,显然 area2( i )是随 i 非递增的,物品1同理,并且这里的容量是固定的,

所以其在以物品2的数目为x轴,最大价值为 y 轴的直角坐标系中的图形为:

  1,若物品1, 2的体积和不大于背包剩余空间,则其为单峰函数的左侧;

  2,对于物品1, 2的体积和大于背包剩余空间,有:

    a,若area2(index2) > area1(1),其中index2为物品2的数目,则其为单峰函数左侧;

    b,若area2(1) < area1(index1),其中index1为物品1的数目,则其为单峰函数右侧;

    c,其他情况则存在峰;

对于单峰函数直接三分一下物品2的数目即可找峰值,注意这里可能会存在单调的情况(为单峰函数的一侧),所以还要判断一下边界;

ps:我试了下先枚举物品3再三分物品1的数目wa了,百思不得其解,望路过的大佬指教~

代码:

 #include <iostream>
#include <stdio.h>
#include <algorithm>
#define ll long long
using namespace std; const int MAXN = 3e5+;
ll a[MAXN], b[MAXN], c[MAXN];
ll va[MAXN], vb[MAXN], vc[MAXN];
int n, m, indxa=, indxb=, indxc=; bool cmp(ll a, ll b){
return a > b;
} void get_v(void){
for(int i=; i<=m; i++){
va[i] = va[i-] + a[i];
}
for(int i=; i*<=m; i++){
vb[i<<] = vb[(i-)<<] + b[i];
vb[(i<<)-] = vb[(i-)<<];
}
for(int i=; i*<=m; i++){
vc[i*] = vc[(i-)*] + c[i];
}
} ll f(int x, int w){
if(x* > w) x=w>>;
return vb[x*] + va[w-x*];
} ll find(int w){//三分体积为2的数目
if(w <= ) return ;
int l=, r=w, rmid=w, lmid=;
while(l < r-){
lmid = l+(r-l)/;
rmid = r-(r-l)/;
if(f(lmid, w) > f(rmid, w)) r = rmid;
else l = lmid;
}
return max(max(max(max(f(l, w), f(r, w)), f(lmid, w)), f(rmid, w)), f(, w));//***注意这里的边界条件
} int main(void){
ll ans=;
scanf("%d%d", &n, &m);
for(int i=; i<n; i++){
int x, y;
scanf("%d%d", &x, &y);
if(x == ) a[indxa++] = y;
else if(x == ) b[indxb++] = y;
else c[indxc++] = y;
}
sort(a+, a+indxa, cmp);
sort(b+, b+indxb, cmp);
sort(c+, c+indxc, cmp);
get_v();
for(int i=; i*<=m; i++){//枚举体积为3的数目
ll cnt = vc[i*];
cnt += find(m-i*);
ans = ans > cnt ? ans : cnt;
}
printf("%lld\n", ans);
return ;
}

cf808E(三分)的更多相关文章

  1. hdu3714 三分找最值

    Error Curves Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  2. BZOJ 1857 传送带 (三分套三分)

    在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在lxhgww想从 ...

  3. hdu 4717(三分求极值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4717 思路:三分时间求极小值. #include <iostream> #include ...

  4. HDU2438 数学+三分

    Turn the corner Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  5. 三分之一的程序猿之社交类app踩过的那些坑

    三分之一的程序猿之社交类app踩过的那些坑 万众创新,全民创业.哪怕去年陌生人社交不管融资与否都倒闭了不知道多少家,但是依然有很多陌生人社交应用层出不穷的冒出来.各种脑洞大开,让人拍案叫起. 下面我们 ...

  6. 基于jPlayer的三分屏制作

    三分屏,这里的三分屏只是在一个播放器里同时播放三个视频,但是要求只有一个控制面板同时控制它们,要求它们共享一个时间轨道.这次只是简单的模拟了一下功能,并没有深入的研究. 首先,需要下载jPlayer, ...

  7. 【BZOJ-1857】传送带 三分套三分

    1857: [Scoi2010]传送带 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 1077  Solved: 575[Submit][Status][ ...

  8. ACM : HDU 2899 Strange fuction 解题报告 -二分、三分

    Strange fuction Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  9. bzoj1857: [Scoi2010]传送带--三分套三分

    三分套三分模板 貌似只要是单峰函数就可以用三分求解 #include<stdio.h> #include<string.h> #include<algorithm> ...

随机推荐

  1. spring运行步骤

    Spring确实使你能通过最简单可行的解决的方法来解决你的问题. 而这是有有非常大价值的.同一时候他的源码的设计理念也受到非常多程序猿的追捧,简洁,易用.但是从哪着手研究Spring却是非常多新手头疼 ...

  2. Pandas一些小技巧

    Pandas有一些不频繁使用容易忘记的小技巧 1.将不同Dataframe写在一个Excel的不同Sheet,或添加到已有Excel的不同Sheet(同名Sheet会覆盖) from pandas i ...

  3. c#应用程序带参数运行

    有时候我们需要让软件带参数运行,使用参数控制软件的部分行为, C#默认窗口应用是不带参数的,不过在Main函数的参数手动加上就可以得到参数了. 举例如下: /// <summary> // ...

  4. 怎么样写一个能告诉你npm包名字是否被占用的工具

    事情是这样的: 因为我经常会写一些npm包,但是有时候我写完一个包,npm publish 的时候却被提示说包名字被占用了,要不就改名字,要不就加scope,很无奈.npm 命令行可以通过 npm v ...

  5. 51nod 1040

    题目 题解:我们要求的是这个式子: $ \sum\limits_{i = 1}^n {\gcd (n,i)}  $ (下面式子中的d都是n的因子) 变形下  $ \sum\limits_{d = 1} ...

  6. RQNOJ 429 词链:单调栈

    题目链接:https://www.rqnoj.cn/problem/429 题意: 如果一张由一个词或多个词组成的表中,每个单词(除了最后一个)都是排在它后面的单词的前缀,则称此表为一个词链. 如:i ...

  7. enable nested VT in VM

    问题描述: 处理器支持VT-x,并且已经在BIOS中开启了VT-x.在host os上用VMware Workstation安装了一个Ubuntu虚拟机,在虚拟机中执行“cat /proc/cpuin ...

  8. 揭秘FaceBook Puma演变及发展——FaceBook公司的实时数据分析平台是建立在Hadoop 和Hive的基础之上,这个根能立稳吗?hive又是sql的Map reduce任务拆分,底层还是依赖hbase和hdfs存储

    在12月2日下午的“大数据技术与应用”分论坛的第一场演讲中,来自全球知名互联网公司——FaceBook公司的软件工程师.研发经理邵铮就带来了一颗重磅炸弹,他将为我们讲解FaceBook公司的实时数据处 ...

  9. certbot申请SSL证书及中间证书问题

    首先是到https://certbot.eff.org/上申请证书,由于我们使用的web服务器是基于erlang的cowboy的,在主页上没有选项可以支持,因此在Software下拉项中选择" ...

  10. leetcode 67. Add Binary (高精度加法)

    Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...