bzoj3874 宅男计划 三分 贪心

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3874

题意:有许多种食品,每种有价格、保质期两种属性,一个人有一个数目的钱,求这个人可以活多久。

如果数据范围小一点那这个显然可以$DP$……然而$0<=Si<=(10^{18}),1<=F,Pi,M<=(10^{18}),1<=N<=200$……我也很绝望啊……

首先这个东西是个凸函数(为什么?我不知道联想生活实际),也就是存活天数是与送餐次数成凸函数(其实不是严格单峰,但在本题可以忽略),那么我们显然可以三分求出最大函数值。

问题变为给出一个$x$,如何求出一个$y$。

根据贪心原则,保质期短价格贵的直接扔掉,于是我们先预处理一下,预处理完之后我们就挨个购买,考虑这个东西每次可以购买的数量。注意最后可能还剩下一些钱够买几次但是不足够每次都买,这一部分也要加以考虑。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int maxn=205;
 7 struct food
 8 {
 9     long long p,s;
10 }fin[maxn],sta[maxn];
11 inline bool comp(const food &x,const food &y)
12 {
13     if(x.s!=y.s)return x.s<y.s;
14     return x.p<y.p;
15 }
16 inline bool cmp(const food &x,const food &y)
17 {
18     return x.p<y.p;
19 }
20 long long m,f;int p,n;
21 inline long long F(long long val)
22 {
23     long long tmp=m-f*val,day=0,ans=0;
24     if(tmp<0)return 0;
25     for(int i=1;i<=p;i++)
26     {
27         if(fin[i].s>=day)
28         {
29             long long con=fin[i].s-day+1ll;
30             long long liv=min(con,tmp/(fin[i].p*val));
31             ans+=liv*val;day+=liv;tmp-=fin[i].p*val*liv;
32         }
33         if(fin[i].s>=day)
34         {
35             long long liv=min(val,tmp/fin[i].p);
36             ans+=liv;day++;tmp-=fin[i].p*liv;
37         }
38     }
39     return ans;
40 }
41 int haha()
42 {
43     scanf("%lld%lld%d",&m,&f,&n);
44     for(int i=1;i<=n;i++)scanf("%lld%lld",&sta[i].p,&sta[i].s);
45     sort(sta+1,sta+n+1,comp);p++,fin[p]=sta[1];
46     for(int i=1;i<=n;i++)
47         if(fin[p].s<sta[i].s)p++,fin[p]=sta[i];
48     sort(fin+1,fin+p+1,cmp);
49     long long l=1,r=m/(f+fin[1].p);
50     long long ans=max(F(l),F(r));
51     while(r-l>=10)
52     {
53         long long mid1=l+(r-l+1)/3,mid2=r-(r-l+1)/3;
54         if(F(mid1)<F(mid2))l=mid1,ans=max(ans,F(mid1));
55         else r=mid2,ans=max(ans,F(mid2));
56     }
57     for(long long i=l;i<=r;i++)ans=max(ans,F(i));
58     printf("%lld\n",ans);
59 }
60 int sb=haha();
61 int main(){;}
bzoj3874

 

转载于:https://www.cnblogs.com/Loser-of-Life/p/7623373.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值