Luogu4040 AHOI/JSOI2014 宅男计划 贪心、二分、三分
仍然对“为什么这个函数单峰”的问题毫无理解
首先,对于保质期又低、价格又贵的食物,我们显然不需要购买它。所以如果设\(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 宅男计划 贪心、二分、三分的更多相关文章
- 【BZOJ3874】[AHOI&JSOI2014]宅男计划(贪心,三分)
[BZOJ3874][AHOI&JSOI2014]宅男计划(贪心,三分) 题面 BZOJ 洛谷 题解 大力猜想一最长的天数和购买外卖的总次数是单峰的.感性理解一下就是买\(0\)次是\(0\) ...
- 洛谷$P4040\ [AHOI2014/JSOI2014]$宅男计划 贪心
正解:三分+贪心 解题报告: 传送门$QwQ$ 其实很久以前的寒假就考过了,,,但那时候$gql$没有好好落实,就只写了个二分,并没有二分套三分,就只拿到了$70pts$ #include <b ...
- [luogu] P4040 [AHOI2014/JSOI2014]宅男计划(贪心)
P4040 [AHOI2014/JSOI2014]宅男计划 题目背景 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY不得不依靠叫外卖来维持生计. 题目描述 外卖店一共有N种食物, ...
- Bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划 三分+贪心
3874: [Ahoi2014&Jsoi2014]宅男计划 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 861 Solved: 336[Su ...
- bzoj3874&2832 [Ahoi2014]宅男计划 模拟退火,三分
[Ahoi2014&Jsoi2014]宅男计划 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 962 Solved: 371[Submit][ ...
- BZOJ3874:[AHOI2014&JSOI2014]宅男计划(爬山法)
Description [故事背景] 自从迷上了拼图,JYY就变成了个彻底的宅男.为了解决温饱问题,JYY 不得不依靠叫外卖来维持生计. [问题描述] 外卖店一共有N种食物,分别有1到N编号.第i种 ...
- bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划
Description 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的 ...
- food(洛谷P4040 [AHOI2014/JSOI2014]宅男计划)
题目在这里 题目描述 外卖店一共有N种食物,分别有1到N编号.第i种食物有固定的价钱Pi和保质期Si.第i种食物会在Si天后过期.JYY是不会吃过期食物的. 比如JYY如果今天点了一份保质期为1天的食 ...
- Luogu P4040 [AHOI2014/JSOI2014]宅男计划
题目 显然存活天数与叫外卖次数的函数是凸函数. 所以三分买外卖的次数. 然后把食品按保质期升序排序. 并且单调栈搞一下,把又贵又保质期短的丢掉. 那么随着保质期的增加,食品的价格一定上涨. 所以我们从 ...
随机推荐
- spring 开发 Tars
和不使用 Spring 的 tars HelloWord 项目相比,客户端完全一样,服务端两个地方不一样 创建不使用 Spring 的 tars HelloWord 步骤: https://www.c ...
- BI怎么选?重点看这10个技术指标
2016年,商业智能市场火热,不管是投资圈还是IT圈,都在广泛关注着大数据和商业智能.宣传广告媒体报道见多了,不知道大家对BI选型的技术标准有谱了没.笔者对Gartner的BI魔力象限考评的15个关键 ...
- springboot中使用mybatis显示执行sql
springboot 中使用mybatis显示执行sql的配置,在properties中添加如下 logging.你的包名=debug 2018-11-27 16:35:43.044 [DubboSe ...
- [20171113]修改表结构删除列相关问题2.txt
[20171113]修改表结构删除列相关问题2.txt --//测试看看修改表结构删除列产生的redo向量,对这些操作细节不了解,分析redo看看. 1.环境:SCOTT@book> @ &am ...
- tkinter调取签名网而设计签名页面(十七)
# --*-- coding:utf-8 --*-- import tkinter as tk import re import requests from tkinter import messag ...
- sql server自定义函数学习笔记
sql server中函数分别有:表值函数.标量函数.聚合函数.系统函数.这些函数中除系统函数外其他函数都需要用户进行自定义. 一.表值函数 简单表值函数 创建 create function fu_ ...
- IE push方法,最后一个参数后面不能跟",",否则报语法错误
var columns = [[]]; columns[0].push( { field: 'ADDNAME', title: '添加人', width: 80, }, { field: 'ADDDT ...
- Red5视频流服务器安装
一.安装jre JAVA运行时下载地址: https://www.java.com/zh_CN/download/manual.jsp 安装后设置环境变量,变量值是jre的安装路径 二.安装 red5 ...
- JSON数据提取
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写.同时也方便了机器进行解析和生成.JSON在数据交换中起到了一个载体的作用 ...
- python基本数据类型 数字 和 字符串
一.数字 int type可以查看数据类型 将字符串转换为数字: a=" b=int(a) print(type(a)) 以十六进制或者八进制或者二进制的形式转换为十进制: num ...