三分答案然后贪心
单峰的话,可以发现,如果我们外卖的次数过少,那么就会出现一些食品性价比不高的情况;如果次数过多,那么就会浪费外卖运费。
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; typedef long long ll; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(ll &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') c=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } struct data{ ll p,s; bool operator < (const data &B)const{ return s==B.s?p<B.p:s<B.s; } }a[301]; int pnt; inline bool cmp(data A,data B){ return A.p<B.p; } ll m,f,n; inline ll F(ll x) { ll sum=m-f*x,maxt=0,ret=0,itmp; if(sum<0) return 0; for(int i=1;i<=n;i++) { if(maxt<=a[i].s) { itmp=a[i].s-maxt+(ll)1; itmp=min(itmp,sum/(a[i].p*x)); ret+=itmp*x; sum-=a[i].p*x*itmp; maxt+=itmp; } if(maxt<=a[i].s) { itmp=min(x,sum/a[i].p); ret+=itmp; sum-=a[i].p*itmp; maxt++; } } return ret; } int main() { freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(m); read(f); read(n); for(int i=1;i<=n;i++) read(a[i].p),read(a[i].s); sort(a+1,a+n+1); a[++pnt]=a[1]; for(int i=1;i<=n;i++) if(a[i].s>a[pnt].s) a[++pnt]=a[i]; n=pnt; sort(a+1,a+n+1,cmp); ll L=1,R=m/(f+a[1].p); ll ans=max(F(L),F(R)); while(L+12<=R) { ll Ml=L+(R-L+1)/3,Al=F(Ml); ll Mr=L+(R-L+1)*2/3,Ar=F(Mr); if(Al<Ar) ans=max(ans,Al),L=Ml; else ans=max(ans,Ar),R=Mr; } for(ll i=L;i<=R;i++) ans=max(ans,F(i)); printf("%lld\n",ans); return 0; }