1. 程式人生 > >[luogu] P4040 [AHOI2014/JSOI2014]宅男計劃(貪心)

[luogu] P4040 [AHOI2014/JSOI2014]宅男計劃(貪心)

外賣 math 多少 天都 宅男 || += 都是 bre

P4040 [AHOI2014/JSOI2014]宅男計劃

題目背景

自從迷上了拼圖,JYY就變成了個徹底的宅男。為了解決溫飽問題,JYY不得不依靠叫外賣來維持生計。

題目描述

外賣店一共有N種食物,分別有1到N編號。第i種食物有固定的價錢Pi和保質期Si。第i種食物會在Si天後過期。JYY是不會吃過期食物的。

比如JYY如果今天點了一份保質期為1天的食物,那麽JYY必須在今天或者明天把這個食物吃掉,否則這個食物就再也不能吃了。保質期可以為0天,這樣這份食物就必須在購買當天吃掉。

JYY現在有M塊錢,每一次叫外賣需要額外付給送外賣小哥外送費F元。

送外賣的小哥身強力壯,可以瞬間給JYY帶來任意多份食物。JYY想知道,在滿足每天都能吃到至少一頓沒過期的外賣的情況下,他可以最多宅多少天呢?

輸入輸出格式

輸入格式:

第一行包含三個整數M,F和N。

接下來N行,第i行包含兩個整數Pi和Si。

輸出格式:

輸出僅包含一行一個整數表示JYY可以宅的最多的天數。

輸入輸出樣例

輸入樣例#1: 復制

32 5 2
5 0
10 2

輸出樣例#1: 復制

3

說明

【樣例說明】

JYY的最佳策略是:

第一天買一份食物1和一份食物2並且吃一份食物1;

第二天吃一份食物2;

第三天買一份食物1並且吃掉。

【數據規模與約定】

對於100%的數據滿足0<=Si<=10^18,1<=F,Pi,M<=10^18,1<=N<=200

題解

很久以前的考試題目了。
其實貪心的過程很好想。

優先便宜且保質期長。在這種條件下能買就買。

但是,鬼知道我要讓外賣小哥來幾次啊??枚舉肯定是TLE飛起。
網上題解感性理解:
叫外賣小哥太少,會被迫買一些性價比低的食物。
叫外賣小哥太多,會因為付太多錢而買不起食物。
所以我們用三分???
網上都是這麽說的qwq,不會證明。

題解

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#include<iostream>
using namespace std;
ll n,f,m,l=1,r,s;
ll v,b,ans,now,w,k,p,j;
struct node{
    ll p,s;
}a[1001];
ll read(){
    ll x=0,w=1;char ch=getchar();
    while(ch>'9'||ch<'0'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*w;
}

bool cmp(node a,node b){
    if(a.p==b.p)return a.s<b.s;
    return a.p<b.p;
}

ll query(ll t){
    v=m-t*f;w=v/t;k=v-w*t;
    ans=0;now=0;if(v<0)return 0;
    for(ll i=1;i<=n;i++){
        if((a[i].s>=now)&&(w-a[i].p>=0)){
            p=min(a[i].s-now+1,w/a[i].p);
            now+=p; w-=p*a[i].p;
        }j=i;
        if(w<a[i].p)break;
    }k+=w*t;
    for(ll i=j;i<=n;i++){
    if((a[i].s)>=now&&(k-a[i].p>=0))
        p=min(k/a[i].p,t),ans+=p,k-=p*a[i].p;
    }
    return t*now+ans;
}

int main(){
    m=read();f=read();n=read();
    for(ll i=1;i<=n;i++)a[i].p=read(),a[i].s=read();
    sort(a+1,a+n+1,cmp);
    if(f)r=(m/f)+1;else r=m+1;
    while(l<r){
        ll midl=l+(r-l)/3;
        ll midr=r-(r-l)/3;
        if(query(midl)>=query(midr))r=midr-1;
        else l=midl+1;
    }
    cout<<query(l)<<endl;
    return 0;
}

[luogu] P4040 [AHOI2014/JSOI2014]宅男計劃(貪心)