[Luo Gu P4040] AHOI2014 otaku plan

Topic background

Since fascinated by puzzles, JYY becomes a thorough otaku. In order to solve the problem of food and clothing, JYY had to rely on takeout to maintain their livelihood.

Problem Description

Takeaways a total of N kinds of food, there are 1 to N number. The first kind of food i have a fixed price and shelf life of Pi Si. I-Si kinds of food expire in days. JYY not eaten in food.

For example, if today JYY ordered a shelf life of one day's food, then JYY we must put this food to eat tomorrow or today, otherwise the food can no longer eat. Shelf life can be 0 days, so this food must be eaten on the day of purchase.

JYY now has M dollars every takeout food delivery need to pay extra delivery fee Small-brother F yuan.

Food delivery brother able-bodied, you can instantly bring any food to more than JYY. JYY want to know, in the case of at least able to eat a meal a day to meet not expired takeaway, he can house up to how many days?

Input Format

The first line contains three integers M, F and N.

Next N lines, comprising two integers i-th row Pi and Si.

Output Format

Output a line containing only a integer number JYY can house a maximum of days.

Sample input

32 5 2
5 0
10 2

Sample Output

3

Explanation

[Sample Description]

JYY best strategy is to:

The first day to buy a food and a food 2 and 1 serving of food 1;

The next day eat a food 2;

1 and the third day to buy a food eaten.

[Agreed] with the scale data

To 100% of the data satisfies 0 <= Si <= 10 ^ 18,1 <= F, Pi, M <= 10 ^ 18,1 <= N <= 200

Resolve

First, the more important is the number of times and days can be seen live food delivery is the relationship between a single peak function. So we can use the rule of thirds seeking maximum.

The question now is how the number of days the number of known food delivery can live up to the requirements. Consider every delivery boy were greedy, certainly from the cheapest to buy from, eat, eat a few days a few days, eat a cheap buy twice. Finally, we definitely left the money, that is, each of the remainder. For the remainder of this section, we use the same method to greedy, but not as a separate takeaway. So, when we buy takeaway begin before the greedy and not from the cheapest to start.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#define int long long
#define N 202
using namespace std;
struct food{
    int p,s;
}a[N];
int n,m,f,i;
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
int my_comp(const food &x,const food &y)
{
    if(x.p==y.p) return x.s>y.s;
    return x.p<y.p;
}
int cal(int x)
{
    int sum=m-x*f,ave=sum/x,rem=sum-ave*x,ans1=0,ans2=0,j=1;
    for(int i=1;i<=n;i++){
        if(a[i].s>=ans1&&ave>=a[i].p){
            int tmp=min(a[i].s-ans1+1,ave/a[i].p);
            ans1+=tmp;
            ave-=tmp*a[i].p;
        }
        if(ave<a[i].p){
            j=i;
            break;
        }
    }
    rem+=ave*x;
    for(int i=j;i<=n;i++){
        if(a[i].s>=ans1&&rem>=a[i].p){
            ans2=min(rem/a[i].p,x);
            break;
        }
    }
    return ans1*x+ans2;
}
signed main()
{
    m=read();f=read();n=read();
    for(i=1;i<=n;i++) a[i].p=read(),a[i].s=read();
    sort(a+1,a+n+1,my_comp);
    int l=1,r,midl,midr;
    if(f!=0) r=(m/f)+1;
    else r=m+1;
    while(l<r){
        midl=l+(r-l)/3;
        midr=r-(r-l)/3;
        if(cal(midl)>=cal(midr)) r=midr-1;
        else l=midl+1;
    }
    printf("%lld\n",cal(l));
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11876741.html