zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    通过抓包软件Charles和Fiddle快速模拟(Mock)数据
    截图+贴图工具 Snipaste
    二、Vuex State
    一、Vuex 的概念及安装使用
    一、记录Git使用中遇到的问题及解决方法
    编译Less文件
    Less的基本使用
    二、Git基础操作
    三、Git常用命令
    sql server 自增长字段,标识值重置
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7623182.html
Copyright © 2011-2022 走看看