1 条题解

  • 0
    @ 2025-8-24 22:45:34

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar MiPloRAs_3316
    けっしょうばん 可爱捏 ⎛⎝≥⏝⏝≤⎛⎝ || 我哀

    搬运于2025-08-24 22:45:34,当前版本为作者最后更新于2023-04-17 14:12:33,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    题目传送门 | 珂能更好的食用体验

    题意概述

    • 奶牛需要为 TA 的 nn 个朋友制作糕点(aia_iAAbib_iBB)。每个朋友最多等待 cic_i 个单位时间,如果没有拿到糕点,TA 就会伤心地离开。
    • 制作 11AA 需要 tct_c 个单位时间,制作 11BB 需要 tmt_m 个单位时间。
    • 奶牛可以花费 ¥11 去升级 TA 的烤箱。升级后,可以少花 11 个单位时间来生产 11AA 或少花 11 个单位时间来生产 11BB
    • 求出她必须花费的最少的 money,以便她的面包店能够满足所有朋友的需求。

    解题思路

    我们可以先假设对于第 ii 个朋友(订单),需要升级 xxAA 烤箱, yyBB 烤箱。

    于是,显而易见的:(看起来很简洁但一点都不好解)

    $$a_i \times (t_c-x) + b_i \times (t_m-y) \leqslant c_i $$

    mid=x+ymid=x+y,于是:

    $$a_i \times t_c-a_i \times x+b_i \times t_m - b_i \times mid+b_i \times x \leqslant c_i $$$$\therefore (b_i-a_i)\times x \leqslant c_i-a_i \times t_c-b_i\times t_m+b_i\times mid $$

    ki=ciai×tcbi×tm+bi×midk_i=c_i-a_i \times t_c-b_i\times t_m+b_i\times mid

    所以,就可以根据上述不等式进行二分答案了。(二分的当然是 x+yx+y。)

    接下来,浅浅说一下不等式的解集:

    $$\begin{cases}x=\varnothing, &b_i-a_i=0 \\ x\leqslant \dfrac{k_i}{b_i-a_i} , &b_i-a_i>0\\ x\geqslant \dfrac{k_i}{b_i-a_i} , &b_i-a_i<0\end{cases} $$

    上述第 22 个式子用于锁定解集的上限,第 33 个式子用于锁定解集的下限

    同时,xxyy 的值应该为整数。所以为了便于大家理解程序,解集应该写成下面这个亚子。

    $$\begin{cases}x=\varnothing, &b_i-a_i=0 \\\\ x\leqslant \left\lfloor\dfrac{k_i}{b_i-a_i}\right\rfloor , &b_i-a_i>0\\\\ x\geqslant \left\lceil\dfrac{k_i}{b_i-a_i}\right\rceil, &b_i-a_i<0\end{cases} $$

    Code

    #include<bits/stdc++.h>
    using namespace std;
    long long T,n,tc,tM,a[110],b[110],c[110];
    bool check(long long x)
    {
    	long long maxx=min(tc-1,x);
    	long long minn=max(0LL,x-tM+1);
    	for(int i=1; i<=n; i++)
    	{
    		long long k=c[i]-a[i]*tc-b[i]*tM+b[i]*x;
    		if(b[i]-a[i]==0)
    		{	
    			if(k<0) return false;
    		}
    		else if(b[i]-a[i]>0) maxx=min(maxx,(long long)floor(k*1.0/(b[i]-a[i])));//二式
    		else minn=max(minn,(long long)ceil(k*1.0/(b[i]-a[i])));//三式
    	}
    	return maxx>=minn;//判断是否有解
    }
    int main()
    {
    	for(cin>>T;T;T--)
    	{
    		cin>>n>>tc>>tM;
    		for(int i=1; i<=n; i++)
    			cin>>a[i]>>b[i]>>c[i];
    		long long l=-1,r=tc+tM-1;
    		while(l+1<r)//简单的二分答案
    		{
    			long long mid=l+r>>1;
    			if(check(mid)) r=mid;
    			else l=mid;
    		}
    		cout<<r<<endl;
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    8455
    时间
    2000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者