zoukankan      html  css  js  c++  java
  • 【BZOJ3874】[AHOI&JSOI2014]宅男计划(贪心,三分)

    【BZOJ3874】[AHOI&JSOI2014]宅男计划(贪心,三分)

    题面

    BZOJ
    洛谷

    题解

    大力猜想一最长的天数和购买外卖的总次数是单峰的。感性理解一下就是买(0)次是(0),买(inf)次也是(0),在中间某次可能取到最优值。然而这样子可能是多峰的,所以也可以退火处理。
    现在假装我们知道了购买外卖的总次数(k),那么我们的问题就变成了如何确定每种外卖购买方案。
    首先将所有外卖按照价格排序,显然只要没有过期那么一定会购买尽可能多的更便宜的外卖。
    假设对于最便宜的外卖,其过期的天数是(s),那么我们一定会在每次购买的时候都买(s)份,那么接下来的每一份外卖都是类似的处理。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    inline ll read()
    {
    	ll x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    ll m,F,n;
    struct Food{ll p,s;}p[250];
    bool operator<(Food a,Food b){return a.p<b.p;}
    ll Calc(ll c)
    {
    	ll M=m-F*c,ans=0,t=0;if(M<=0)return 0;
    	for(int i=1;i<=n;++i)
    		if(p[i].s>t)
    		{
    			ll d=p[i].s-t;
    			if(1.0*p[i].p*c*d<=M)ans+=c*d,M-=p[i].p*c*d;
    			else{ans+=M/p[i].p;break;}
    			t=p[i].s;
    		}
    	return ans;
    }
    int main()
    {
    	m=read();F=read();n=read();
    	for(int i=1;i<=n;++i)p[i].p=read(),p[i].s=read()+1;
    	sort(&p[1],&p[n+1]);
    	ll l=0,r=m/F,ret=0;
    	while(r-l>=5)
    	{
    		ll p0=l+(r-l+1)/3,p1=r-(r-l+1)/3;
    		ll d0=Calc(p0),d1=Calc(p1);
    		if(d0<=d1)l=p0;else r=p1;
    	}
    	for(ll i=l;i<=r;++i)ret=max(ret,Calc(i));
    	printf("%lld
    ",ret);
    	return 0;
    }
    
  • 相关阅读:
    pyhon学习日记第八天tkinter模块6
    python学习日记第八天tkinter模块5
    python学习日记第七天tkinter模块4
    python学习日记第七天tkinter模块3
    python学习日记第六天tkinter模块2
    python学习日记第六天tkinter模块学习1
    python学习日记第五天(飞机大战)
    python学习日记第四天
    python学习日记第三天(实例)
    Demo Nec
  • 原文地址:https://www.cnblogs.com/cjyyb/p/10572841.html
Copyright © 2011-2022 走看看