bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划
Posted A_LEAF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划相关的知识,希望对你有一定的参考价值。
三分+贪心检验 (注意check的时候,多用/法,不要炸long long)
jyy可以生存的时间 与 买的次数 成一个上凸的单峰函数
证明:
如果买的太多,光小费就给不起
如果买的太少,又不能充分利用多种食物
所以可以三分 买的次数
贪心check:
先把保质期短而且又贵的食物去掉
然后剩下的食物一定是保质期越长越贵
那就从保质期短到长一直买到不能买为止
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; const int N=1006; struct son { ll t,w; }ji[N],q[N]; int con; bool ok_t(son a,son b) { if(a.t==b.t) return a.w<b.w; return a.t<b.t; } bool ok_w(son a,son b) { if(a.w==b.w) //return a.t>b.t; //wrong reason:不能a.t>b.t,因为有可能用到 return a.t<b.t; return a.w<b.w; } int n; ll M,F; ll check(ll x) { ll ans=0,temp,le=M-F*x,fina,can; if(le<0) return 0; for(int i=1;i<=con;++i) { if(le<0) break; temp=le/q[i].w; /*fina=min(temp,q[i].t*x-ans ); if(fina<0) //炸long long了 while(1);*/ can=(temp+ans-1)/x+1; if(can>q[i].t) // T_M_D 炸long long fina=q[i].t*x-ans; else fina=temp; ans+=fina; le-=fina*q[i].w; } return ans; } ll work() { ll ans=0; ll l=1,r=M/(F+q[1].w),mid,midmid,vmid,vmidmid; while(l+15<=r) { mid=l+((r-l)/3); midmid=r-((r-l)/3); vmid=check(mid); vmidmid=check(midmid); if(vmid>vmidmid) { r=midmid; if(ans<vmid) ans=vmid; } else { l=mid; if(ans<vmidmid) ans=vmidmid; } } for(ll i=l;i<=r;++i) { vmid=check(i); if(ans<vmid) ans=vmid; } return ans; } int main(){ //freopen("in.in","r",stdin); scanf("%lld%lld%d",&M,&F,&n); for(int i=1;i<=n;++i) { scanf("%lld%lld",&ji[i].w,&ji[i].t); ++ji[i].t; } sort(ji+1,ji+1+n,ok_w); con=0; q[++con]=ji[1]; for(int i=2;i<=n;++i) if(ji[i].t>q[con].t) q[++con]=ji[i]; //sort(q+1,q+1+con,ok_t); // 已经是按时间排序了.... cout<<work(); }
以上是关于bzoj 3874: [Ahoi2014&Jsoi2014]宅男计划的主要内容,如果未能解决你的问题,请参考以下文章