宅男小C

Time Limit: 10 Sec  Memory Limit: 256 MB
[Submit][Status][Discuss]

Description

  众所周知,小C是个宅男,所以他的每天的食物要靠外卖来解决。小C现在有M元钱,他想知道这些钱他最多可以吃多少天。

  餐厅提供N种食物,每种食物有两个属性,单价Pi和保质期Si,表示小C需要花Pi元才能买到足够一天吃的这种食物,并且需要在送到Si天内吃完,否则食物会变质,就不能吃了,若Si为0则意味着必须在送到当天吃完。另外,每次送餐需要额外F元送餐费。

Input

  每个测试点包含多组测试数据;
  每个测试数据第一行三个整数M,F,N,如题目描述中所述;
  以下N行,每行两个整数,分别表示Pi和Si。

Output

  对于每个测试数据输出一行,表示最多可以吃的天数。

Sample Input

  32 5 2
  5 0
  10 2
  10 10 1
  10 10
  10 1 1
  1 5

Sample Output

  3
  0
  8

HINT

  对于40%的数据,M,Si <= 2*10^6;
  对于100%的数据,1 ≤ N ≤ 200,M, Si<= 10^18,1 ≤ T ≤ 50,1 ≤ F ≤ M,1 ≤ Pi ≤ M。

Main idea

  每种食物有一个花费和一个保质期,在保质期内食用可以多活一天,每次购买可以买多个食物,买一次会耗费一些钱,问最多能活几天。

Solution

  我们先从简单的做法入手,如果确定了购买次数,能求出最多活几天吗?答案是显然可以的。我们运用贪心:首先,若存在某种价格又贵保质期又短的食物显然是没有用的,我们sort一遍直接删去,然后我们可以得到一个价格上升且保质期上升的序列。我们基于这里开始贪心:我们先从便宜的食物入手,显然每次都是从这种食物吃起,仅存在两种不购买便宜的情况:1.保质期过了;2.钱不够满足所有次数了。如果保质期过了,我们就选择下一个食物,如果钱不够满足所有次数了,那就能买几次买几次,记录一下答案,退出。

  我们解决了确定购买次数最多活几天之后,再仔细思考:由于购买会花钱,那么我们大胆猜测购买次数和活的天数有一定的规律,我们画了几张图之后,发现其比例大致单峰,如下图所示:

  我们发现,显然中间有一段波动,那么就不能使用三分法了。那怎么办呢?但是我们再发现:函数最后波动段非常短!显然在随机范围内可行,那么显然我们可以使用随机化算法!这里我们运用模拟退火。直接模拟退火随机一个购买次数,然后Judge更新即可。

  随机化算法是坠吼的!\(≧▽≦)/

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int n;
s64 A,Now,Ans;
s64 Total,F; struct power
{
s64 cost;
s64 days;
}a[ONE]; bool cmp(const power &a,const power &b)
{
if(a.cost == b.cost) return a.days > b.days;
return a.cost < b.cost;
} int get()
{
int res=,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void pre()
{
sort(a+,a+n+,cmp); s64 d=-;
int m=n; n=;
for(int i=;i<=m;i++)
if(a[i].days > d)
a[++n]=a[i], d=a[i].days;
} s64 Judge(s64 times)
{
if(times<=) return ;
s64 Money = Total - times * F;
s64 res = , num, day = ;
for(int i=;i<=n;i++)
{
num = min(Money / a[i].cost / times, a[i].days - day + );
Money -= num * a[i].cost * times;
day += num; res += times * num;
if(day <= a[i].days)
{
num = Money / a[i].cost;
res += num;
Ans = max(Ans, res);
return res;
}
}
Ans = max(Ans, res);
return res;
} double Random() {return rand()/(double)RAND_MAX;}
void SA(double T)
{
Now = ;
while(T >= )
{
A = Now + (s64)(T * (Random()*-)) ;
if(A<=) A = T*Random();
s64 dE = Judge(A) - Judge(Now);
if(dE > )
Now = A;
T *= 0.93;
} } void Solve()
{
for(int i=;i<=n;i++)
scanf("%lld %lld",&a[i].cost,&a[i].days);
pre();
Ans = ;
SA(Total / F + );
printf("%lld\n",Ans);
} int main()
{
while(scanf("%lld %lld %d",&Total,&F,&n) != EOF)
Solve();
}

【BZOJ2832&&3874】宅男小C [模拟退火][贪心]的更多相关文章

  1. Bzoj2832 / Bzoj3874 宅男小C

    Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 124  Solved: 26 Description 众所周知,小C是个宅男,所以他的每天的食物要靠外 ...

  2. BZOJ2832 : 宅男小C

    首先将所有显然不在最优解中的外卖都删去,那么剩下的外卖价格越低,保质期也最短. 考虑三分订外卖的次数,然后贪心求解,每次尽量平均的时候可以做到最优化. 三分的时候,以存活天数为第一关键字,剩余钱数为第 ...

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

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

  4. 外卖(food) & 洛谷4040宅男计划 三分套二分&贪心

    food评测传送门 [题目描述] 叫外卖是一个技术活,宅男宅女们一直面对着一个很大的矛盾,如何以有限的金钱在宿舍宅得尽量久.    外卖店一共有 N 种食物,每种食物有固定的价钱 Pi 与保质期 Si ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. static和final的区别(转载)

    Java中static 和final的区别 final定义的变量可以看做一个常量,不能被改变: final定义的方法不能被覆盖: final定义的类不能被继承. final static 就是再加上s ...

  2. Android adb shell启动应用程序的方法

    在Android中,除了从界面上启动程序之外,还可以从命令行启动程序,使用的是命令行工具am. usage: am [subcommand] [options] start an Activity: ...

  3. ES5新增数组方法(1):filter

    检测数组元素,并返回符合条件所有元素的数组. 1.过滤数组中不符合条件的元素 let arr = [1, 2, 3, 4, 5, 6]; // 方式一 let newArr = arr.filter( ...

  4. C++知识点 内存占用问题

    有一次去面试,谈的挺好的,被人问了一个问题,瞬间暴露自己基础能力弱的弱点了,这里自己记录下,以后慢慢长进. 问题 char test1[]={1,2,3,4}; char test2[]={1,2,3 ...

  5. Wordpress 设置后台自定义post 排序

    创建新的 Post type时,文章在后台默认使用 Titile 列进行升序排序,但是通常情况下我们需要按日期 Date 进行降序排序, function wpse_81939_post_types_ ...

  6. 企业级Tomcat部署配置

    1.1 Tomcat简介 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun和其他一些公司及个人 ...

  7. mysql数据备份和还原

    MySQL是一个永久存储数据的数据库服务器.如果使用MySQLServer,那么需要创建数据库备份以便从崩溃中恢复.mysql提供了一个用于备份的实用程序mysqldump. 1.普通.sql文件中的 ...

  8. sed-awk命令详解

      第2章 ***********sed***********. 1目  录 2.1 -------sed命令小结及小结图---- 1 2.2 -------第几行---------- 2 2.3 - ...

  9. HDU 4571 Travel in time(最短路径+DP)(2013 ACM-ICPC长沙赛区全国邀请赛)

    Problem Description Bob gets tired of playing games, leaves Alice, and travels to Changsha alone. Yu ...

  10. LCA(最近公共祖先)——LCA倍增法

    一.前人种树 博客:最近公共祖先 LCA 倍增法 博客:浅谈倍增法求LCA 二.沙场练兵 题目:POJ 1330 Nearest Common Ancestors 代码: const int MAXN ...