宅男计划:单峰函数三分

Description

自从迷上了拼图,JYY 就变成了个彻底的宅男。为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计。

外卖店一共有n种食物,分别由1到n编号。第i种食物有固定的价钱Pi和保质期Si。第i种食物会在Si天后过期。JYY 是不会吃过期食物的。比如 JYY 如果今天点了一份保质期为0天的食物,那么 JYY 必须在今天或者明天把这个食物吃掉,否则这个食物就再也不能吃了。保质期可以为天,这样这份食物就必须在购买当天吃掉。

JYY 现在有M块钱,每一次叫外卖需要额外付给送外卖小哥外送费F元。送外卖的小哥身强力壮,可以瞬间给 JYY 带来任意多份食物。

JYY 想知道,在满足每天都能吃到至少一顿没过期的外卖的情况下,他可以最多宅多少天呢?

题目链接

首先,这题诡异而无聊的数据范围需要用double来计算费用,再某些特殊数据下计算数据会爆long long。

比较容易发现的就是所有的钱一部分花在了外送费上,另一部分才是买外卖的。

那么如果我们已经确定了我们要点多少次外卖,然后就可以采取最优决策了。

点外卖的次数太多不好,把太多的钱花费在小费上了。

点外卖的次数太少也不好,那样可能就会因为保质期的限制而被迫买更贵的外卖了。

奇妙的单峰函数性质。

具体为什么能看出它是单峰函数。。emm,一是直觉,二是经验。

看起来是对的,而且没有反例啊,那就是对的吧。。。好的,那它就是对的。

三分的大致套路就是就是把函数劈成3个部分,取4个端点根据大小关系来缩小区间。

目前区间的端点是l,r,你要分出的两个新端点为ml,mr。

两种分法:ml=l+(r-l)/3;mr=l+(r-l)*2/3;或ml=l+r>>1;mr=ml+1;

本质是一样的,后者的复杂度更低为2为底的对数,前者的底是1.5。

反正我们已经把函数搞成3段了,然后呢?

我们已经确定最大(小)值已经在[l,r]里了,那么只有3种情况(以求最大值为例):

1)在[l,ml]里,那么就有f(ml)>f(mr)>f(r)

2)在[ml,mr]里,那么有f(ml)>f(mr)>f(r)或f(l)<f(ml)<f(mr)

3)在[mr,r]里,那么有f(l)<f(ml)<f(mr)

所以我们可以发现如果满足f(l)<f(ml)<f(mr)那么答案一定不在[l,ml]里

如果满足f(ml)>f(mr)>f(r)那么答案一定不在[mr,r]里。

与f(l),f(r)的比较没有意义,所以我们关注的就是f(ml),f(mr)的大小关系

根据它们的大小关系我们就可以把答案区间缩小一部分了。

为了防止区间能缩小,我们要确保区间的大小至少是4(l<r-2),最后在3个可能值里取max即可。

1 while(l<r-2){
2     ml=l+r>>1;mr=ml+1;
3     if(f(ml)<f(mr)) l=ml;
4     else r=mr;
5 }
6 ans=max(max(f(l),f(l+1)),f(r));

三分大致框架

那么剩下的问题就是决策/计算了。

显而易见,最便宜的外卖肯定是要买的,那些保质期短而价格高的我们一个也不会买。

那么我们把外卖按价格排序,价格相同的只留下保质期最长的,价格高保质期短的排除。

那么我们就不断买当前最便宜的就可以了,买的钱数是(这个保质期-上一个的保质期)×价格×点外卖次数(可能爆long long)

那么我们在总钱数m里先减去外送费,剩下的钱不断采取上述决策,如果某一种不能全部卖完那么就能买几份买几份。

这样就可以计算出天数了。套个三分,搞定。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 #define int long long
 5 struct ps{int w,t;friend bool operator<(ps a,ps b){return a.w<b.w;}}lp[205],p[205];
 6 int n,m,f,cnt,mx;
 7 int Q(int tms){
 8     int lft=m-f*tms;
 9     for(int i=1;i<=cnt;++i)
10         if(lft/p[i].w>=1.0*tms*(p[i].t-p[i-1].t)){
11             if(i==cnt)return p[i].t*tms;
12             lft-=(p[i].t-p[i-1].t)*p[i].w*tms;
13         }
14         else return p[i-1].t*tms+lft/p[i].w;
15 }
16 signed main(){
17     scanf("%lld%lld%lld",&m,&f,&n);
18     for(int i=1;i<=n;++i)scanf("%lld%lld",&lp[i].w,&lp[i].t),lp[i].t++;
19     sort(lp+1,lp+1+n);
20     for(int i=1;i<=n;++i)if(lp[i].t>mx)p[++cnt]=lp[i],mx=lp[i].t;
21     int l=1,r=m/f,ml,mr,lans,rans;
22     while(l<r-2){
23         ml=l+r>>1;mr=ml+1;
24         lans=Q(ml);rans=Q(mr);
25         if(lans<rans)l=ml;else r=mr;
26     }
27     printf("%lld\n",max(max(Q(l),Q(r)),l+1<=r?Q(l+1):0));
28 }

完整代码811B

原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11425675.html

时间: 2024-11-09 04:11:58

宅男计划:单峰函数三分的相关文章

bzoj3874[Ahoi2014]宅男计划

bzoj3874[Ahoi2014]宅男计划 题意: n种食物,每种有价钱和保质期.每次叫外卖要F元,可以购买任意多份食物.共有m元,问一共能过多少天使得每天都能吃到一份不过期的食物. 题解: 先排序+单调队列去掉那些价钱贵保质期反而短的外卖,剩下的队列按保质期从短到长排(也就是价钱从便宜到贵排).然后有结论:生存天数为以叫外卖次数为自变量的单峰函数.因此三分叫外卖次数(注意上界为m/最便宜外卖的价钱),如何根据叫外卖次数求生存天数呢?又有结论:每次叫外卖间隔时间越平均越优.设叫外卖次数为k,从

bzoj 3874: [Ahoi2014]宅男计划

[AHOI2014/JSOI2014]宅男计划: \(solution:\) 看到这一题题面,莫名想到了(蔬菜),于是莫名开始恐慌.考场上只知道有个贪心计算快递小哥来一次,我要买能活n天的最小花费,却没想到还有一个三分法来枚举快递小哥来的次数! 首先我们可以脑补一下,快递小哥来的次数,和宅男活的总天数是成一个二次函数关系的.就像快递小哥来的次数少,那宅男多数的钱只能分到这么少的购买次数中,因为便宜的保质期短,每次必然会买一些保质期长价格贵的食物:当快递小哥来的次数多了,那我的钱可以分配到很多次购

[luogu] P4040 [AHOI2014/JSOI2014]宅男计划(贪心)

P4040 [AHOI2014/JSOI2014]宅男计划 题目背景 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY不得不依靠叫外卖来维持生计. 题目描述 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的食物,那么JYY必须在今天或者明天把这个食物吃掉,否则这个食物就再也不能吃了.保质期可以为0天,这样这份食物就必须在购买当天吃掉. JYY现在有M

BZOJ 3874([Ahoi2014]宅男计划-dp+三分法+贪心)

3874: [Ahoi2014]宅男计划 Time Limit: 1 Sec  Memory Limit: 256 MB Submit: 66  Solved: 24 [Submit][Status][Discuss] Description [故事背景] 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计. [问题描述] 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食

[AHOI2014/JSOI2014]宅男计划(贪心+三分)

传送门 题意:有N种食物,分别1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期(特别地,如果Si=0,表示今天必须吃掉).现在有M元钱,每一次叫外卖需要额外付给外卖小哥外送费F元.外卖小哥可以一次带来任意多份食物.求在满足每天都能吃到至少一顿没过期的外卖的情况下,最多可以活多少天?(突然想到白夜追凶里有一个案件就是讲的外卖小哥对那些每天宅在家中点外卖的人......额,一部挺好看的悬疑剧) 分析:本题需要我们构造贪心条件.我们现在不知道点了多少次外卖,无从下手,但我

【BZOJ3874】[Ahoi2014]宅男计划【贪心】【模拟退火 / 三分法】

[题目链接] 可以发现,购买方案是有周期的,周期个数即为购买次数. 对于固定的购买次数,我们可以贪心的求出最多存活多少天. 但是我们并不知道要购买多少次,反正是个函数最值问题,直接模拟退火! 看了题解之后,发现购买次数与答案为单峰函数关系,那么可以换成三分法了.. 贪心的话,先预处理出每次要购买的食物(因为有些食物一定不会去买的),然后在保质期内,贪心的全买这种食物即可. /* Telekinetic Forest Guard */ #include <cstdio> #include <

宅男也可变形男-我是如何在11个月零27天减掉80斤的

对我人生态度起到决定性的一个事件 这个事情说起来也是源于98年的一次初中同学聚会,在我的"一切源于一台笔记本"里我提到过,当时我是中专毕业.早早的工作了. 96年11月份开始工作,而当时的初中同学们都还在读高中,一时间觉得自己有收入了可以开销了. 同时我们那个初中和一般学校不一样,因为都是复旦教师的子弟,因此我们从托儿所到幼儿园到小学到初中都是同一批人,感情彼深. 我自己又是一个极念旧情的人,因此一开始有收入后第一件事就是想到的是请以前初中的同学们出来玩,吃饭. 96年开始一年一次,每

老司机太多?为何科技宅男爱“撸串”

"撸",原本是宅男是家里做某些不可言说的事儿的代名词,但随着网络文化的发酵,迅速爆红.尤其是夜市文化,演变成了"撸串文化".一个人撸串,撸的是心情:两个人撸串,撸的是默契:三个人撸串,撸的是江湖.撸串时每个小餐桌都是一个指点江山.挥斥方遒的大舞台.对于科技宅男来说,更是难得的放松机会.那么问题来了,对互联网熟稔至极,个个都是老司机的互联网"民工"们,为何独爱"撸串"? 近日58同城和京东接连被曝光要采用"996&qu

快播公司2.6亿元天价侵权罚款 侵了宅男们的心

 腾讯笑了,快播完了,宅男哭了.小编的手手在颤抖,2.6亿后面是几个零?这可是无数个闷骚小男人辛苦赚来的零花钱啊,全都变相纳税去了,555- 6月26日,快播公司2.6亿罚单正式生效,有关部门限定其在15日内缴清,若逾期不缴,则每日加罚罚款总额的3%(大约为780万元).这是国内对侵权案件的最大罚单,太狠了吧!宅男们掩面哭泣,痛不欲生. 来看看深圳市场监管局稽查大队执法人员将侵权行政处罚2.6亿元罚单送到快播公司的庄严场面吧,罚单即日生效哦!http://www.71shi.net/?p=2