[三分 贪心] BZOJ 3874 [Ahoi2014]宅男计划

三分答案然后贪心

单峰的话,可以发现,如果我们外卖的次数过少,那么就会出现一些食品性价比不高的情况;如果次数过多,那么就会浪费外卖运费。


#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;
}


你可能感兴趣的:([三分 贪心] BZOJ 3874 [Ahoi2014]宅男计划)