传送门


仍然对“为什么这个函数单峰”的问题毫无理解

首先,对于保质期又低、价格又贵的食物,我们显然不需要购买它。所以如果设\(pri_i\)表示保质期不小于\(i\)的所有食品中价格最低的食品的价格,那么\(pri\)数组显然单调不降。

考虑如果我们要直接去做比较麻烦,可是如果我们知道点外卖的次数,就很好计算了。

假设我们知道了我们总共要买\(x\)次外卖,不难知道这\(x\)次外卖点的食物能够坚持的时间的极差不会超过\(1\),否则可以用多的补少的,在不降低总坚持时间的情况下降低总价格(因为\(pri\)单调不降)。

假设\(x\)次外卖坚持的时间为\(K\)与\(K+1\),那么可以先二分出\(K\),然后将剩下的钱尽可能多的买\(pri_{K+1}\)。

现在,确定点外卖的次数就可以求得对应的能够坚持的时间,问题就是如何求最长的时间。不难发现点外卖的次数与坚持的时间对应的函数是一个单峰函数,直接上三分就完事了。

有没有神仙会证这个函数单峰啊QAQ

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<cstring>
#include<iomanip>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<vector>
#include<cmath>
#define INF 0x3f3f3f3f
#define int long long
#define PII pair < int , int >
#define st first
#define nd second
//This code is written by Itst
using namespace std; inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c) && c != EOF){
if(c == '-')
f = 1;
c = getchar();
}
if(c == EOF)
exit(0);
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
} vector < PII > tg;
vector < PII > :: iterator it , it1;
int M , F , N , sum[210];
bool f[210]; inline int calcSum(int dir){
it = lower_bound(tg.begin() , tg.end() , PII(dir , -1));
int t = it - tg.begin();
if(t && !f[t - 1] || (t ? sum[t - 1] : 0) + 1.0 * tg[t].nd * (dir - (t ? tg[t - 1].st : -1)) > M)
return 2e18;
return (t ? sum[t - 1] : 0) + tg[t].nd * (dir - (t ? tg[t - 1].st : -1));
} inline int calc(int x){
int s = M - x * F , L = -1 , R = tg[N - 1].st;
while(L < R){
int mid = L + R + 1 >> 1;
calcSum(mid) <= s / x ? L = mid : R = mid - 1;
}
s -= calcSum(L) * x;
if(L == tg[N - 1].st)
return (L + 1) * x;
it = lower_bound(tg.begin() , tg.end() , PII(L + 1 , -1));
return (L + 1) * x + s / it->second;
} inline bool check(int mid){
return calc(mid) >= calc(mid + 1);
} signed main(){
#ifndef ONLINE_JUDGE
//freopen("in" , "r" , stdin);
//freopen("out" , "w" , stdout);
#endif
M = read();
F = read();
N = read();
for(int i = 1 ; i <= N ; ++i){
int a = read() , b = read();
tg.push_back(PII(b , a));
}
sort(tg.begin() , tg.end());
for(it = --tg.end() , it1 = it , --it1 ; it != tg.begin() ; --it , it1 = it , --it1)
if(it->nd < it1->nd)
it1->nd = it->nd;
for(it = tg.begin() , it1 = it , ++it1 ; it1 != tg.end() ; ++it , it1 = it , ++it1)
if(it->st == it1->st)
it1->nd = it->nd;
for(int i = 0 ; i < N ; ++i)
if((i == 0 ? 0 : sum[i - 1]) + 1.0 * tg[i].nd * (tg[i].st - (i == 0 ? -1 : tg[i - 1].st)) <= M){
f[i] = 1;
sum[i] = (!i ? 0 : sum[i - 1]) + tg[i].nd * (tg[i].st - (!i ? -1 : tg[i - 1].st));
}
else
break;
int L = 1 , R = M / F;
while(L < R){
int mid = (L + R) >> 1;
check(mid) ? R = mid : L = mid + 1;
}
cout << calc(L);
return 0;
}

Luogu4040 AHOI/JSOI2014 宅男计划 贪心、二分、三分的更多相关文章

  1. 【BZOJ3874】[AHOI&JSOI2014]宅男计划(贪心,三分)

    [BZOJ3874][AHOI&JSOI2014]宅男计划(贪心,三分) 题面 BZOJ 洛谷 题解 大力猜想一最长的天数和购买外卖的总次数是单峰的.感性理解一下就是买\(0\)次是\(0\) ...

  2. 洛谷$P4040\ [AHOI2014/JSOI2014]$宅男计划 贪心

    正解:三分+贪心 解题报告: 传送门$QwQ$ 其实很久以前的寒假就考过了,,,但那时候$gql$没有好好落实,就只写了个二分,并没有二分套三分,就只拿到了$70pts$ #include <b ...

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

    P4040 [AHOI2014/JSOI2014]宅男计划 题目背景 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY不得不依靠叫外卖来维持生计. 题目描述 外卖店一共有N种食物, ...

  4. Bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划 三分+贪心

    3874: [Ahoi2014&Jsoi2014]宅男计划 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 861  Solved: 336[Su ...

  5. bzoj3874&2832 [Ahoi2014]宅男计划 模拟退火,三分

    [Ahoi2014&Jsoi2014]宅男计划 Time Limit: 1 Sec  Memory Limit: 256 MBSubmit: 962  Solved: 371[Submit][ ...

  6. BZOJ3874:[AHOI2014&JSOI2014]宅男计划(爬山法)

    Description  [故事背景] 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计. [问题描述] 外卖店一共有N种食物,分别有1到N编号.第i种 ...

  7. bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划

    Description 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的 ...

  8. food(洛谷P4040 [AHOI2014/JSOI2014]宅男计划)

    题目在这里 题目描述 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的食 ...

  9. Luogu P4040 [AHOI2014/JSOI2014]宅男计划

    题目 显然存活天数与叫外卖次数的函数是凸函数. 所以三分买外卖的次数. 然后把食品按保质期升序排序. 并且单调栈搞一下,把又贵又保质期短的丢掉. 那么随着保质期的增加,食品的价格一定上涨. 所以我们从 ...

随机推荐

  1. Linux 磁盘使用查看 查看使用磁盘程序 Monitoring disk activity in linux

    5 TOOLS FOR MONITORING DISK ACTIVITY IN LINUX Here is a quick overview of 5 command-line tools that ...

  2. 给你一个全自动的屏幕适配方案(基于SW方案)!—— 解放你和UI的双手

    Calces系列相关文章:Calces自动实现Android组件化模块构建 前言 屏幕适配一直是移动端开发热议的问题,但是适配方案往往在实际开发的时候会和UI提供的设计稿冲突.本文主要是基于官方推荐的 ...

  3. CSS3伪类和伪元素

    作为一个CSS3初学不久者来说,很容易混淆单冒号(:)和双冒号(::)的用法,以为两者可以互换着来使用.我自己之前也混淆过他们,因为两者看起来太相像了,就像孪生兄弟.但实际上,他们的区别还是挺大的,最 ...

  4. [20171120]关于find 软连接问题.txt

    [20171120]关于find 软连接问题.txt --//上个星期为了测试oracle参数filesystemio_options,将数据库做了一次移动.但是我使用find对软链接目录查询时--/ ...

  5. 洗礼灵魂,修炼python(49)--巩固篇—包

    包(Package) 这个其实前面也说过的,不过同模块一样,没有具体的解析 1.什么是包 在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,那么此文件夹(目录)即为包,文件夹( ...

  6. vs2012\2013\2015 添加 ActiveX制作控件插件 Visual Studio Installer

    由于vs2012.2013 之后的版本升级,之前用vs2010 开发制作的ActvieX控件在高版本12.13上不兼容,需要安装插件支持: 如果是vs2013版本,可参照以下方式下载后安装,若是其他版 ...

  7. gitlab 和 github 配置 SSH Keys

    gitlab 文档上给了很好的配置的例子:https://gitlab.com/help/ssh/README#locating-an-existing-ssh-key-pair 针对mac 下的使用 ...

  8. Kubernetes 核心概念

    什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...

  9. 4.91Python数据类型之(6)元组

    前言 有时候,我们为了数值的安全性,不许用户修改数据,今天我们就来讲讲关于python不可变的数据类型--- 元组数据 目录 1.元组的基本定义 2.元组的基本操作 (一)元组的基本定义 1.元组的概 ...

  10. SAP ABAP 查找用户出口

    1.查找事物代码程序名 2.查找用户出口 T-CODE:SE80 在子例程中查找以USEREXIT开头的子程序.