题目大意
给你一共n种食物,每种食物有两个参数p,s,分别表示价格为p,保质期为s。然后你以叫外卖的形式去购买食物,每种食物都有无限多,你每叫一次外卖都要花费f元,你每次叫的外卖都可以叫无限多次,然后你一共有m元,试求你最多能连续多少天吃到食物。
分析
- 题目大意说得好像不是很清楚,不过没事题面各大OJ都有。这道题用到了一个比较少用的算法——三分法。首先有个很显然但很重要的预处理,你一定要先将那些价格又高保质期又短的食品全部淘汰掉,可以用到一个单调栈即可。主体部分不妨可以脑补一下,点的外卖次数多了配送费就多了,但是单次购买的费用就少了(因为预处理过后保质期越短价格一定越小),但是如果外卖次数少了拿花费的费用就多了,因此这是一个类似于开口向下的二次函数,所以我们需要用到三分法,不断往中间靠,直到找出最大值。总的来说二分法适用于单调递增或单调递减的情况,三分法适用于先增后减或先减后增的情况。
- 但是鉴于本题的特殊性我们不三分答案而是三分点外卖的次数。对于每一个mid我们要求出再点外卖次数为mid次的情况下能最多连续吃到食物的天数,至于如何处理出这个答案,我们不难发现这个最优情况一定是一个个循环节一样的模式,然后最后若没办法补齐就直接补到哪算哪。
Code
#include <cstdio>
#include <algorithm>
#define ll long long
using namespace std;
const int N = 220;
struct Node{
ll p,s;
} a[N],b[N];
ll m,f,n,ans;
ll l,r,mid1,mid2,top;
ll read()
{
ll x = 0;
char ch = getchar();
while (ch < '0' || ch > '9') ch = getchar();