首页 > 其他分享 >ABC374E 题解

ABC374E 题解

时间:2024-10-06 09:49:00浏览次数:7  
标签:10 cnt int 题解 ll mid 物品 ABC374E

好题。爱做。


标签:二分。

求最大的最小值,考虑二分答案。然后问题就转化成了(求 \(n\) 次):有两种物品,每种物品有一个代价和价值,求获得不少于给定价值所需的最小代价。

下文记物品的代价为 \(w\),价值为 \(v\),所拿的数量为 \(cnt\)。

假设有两种物品 \(S\) 与 \(T\),\(S\) 物品的性价比(价值 / 代价)比 \(T\) 高,那么有一种较优的拿法是全拿 \(S\)。但手玩一下发现,这不一定是最优的。那我们从大到小枚举所拿 \(S\) 物品的个数,剩下的价值用 \(T\) 物品补齐,然后计算出代价,取最小值即可。

但是直接枚举是会 TLE 的。注意到当我们拿了很多的 \(T\) 物品的时候,我们把若干 \(T\) 物品替换成相同价值的 \(S\) 物品会更优。具体地说,假如 \(cnt_T \times v_T\) 是 \(v_S\) 的倍数,那我们只需要把所有的 \(T\) 物品换成 \(\frac{cnt_T \times v_T}{v_S}\) 个 \(S\) 物品即可。

所以,\(cnt_T\) 的上界为 \(\text{lcm}(v_T, v_S) / v_T\),再拿多就不优了。由于 \(\text{lcm}(v_T, v_S) \le v_T \times v_S\),同理可以计算出少拿 \(S\) 物品的个数的上界,因此枚举上界不会超过 \(10^4\)。

然后就做完了。时间复杂度 \(O(n k\log V)\)。\(k\) 是单组枚举上界,不超过 \(10^4\);\(V\) 是二分价值的值域,不超过 \(10^9\)。

(我赛时更豪放一点,\(k\) 开到了 \(10^5\))

code :

#include <iostream>
#include <cstdio>
using namespace std;

typedef long long ll;
typedef double db;
const int N = 110;
int a[N], b[N], c[N], d[N], n;
ll X;

ll get(ll i, ll x) {
    db c1 = b[i] * 1.0 / a[i], c2 = d[i] * 1.0 / c[i];
    if(c1 > c2) swap(a[i], c[i]), swap(b[i], d[i]);
    ll cnt1 = (x + a[i] - 1) / a[i], res = 1e18;
    int k = 0;
    while(~cnt1 && k <= 100000) {
        ll cnt2 = (max(0ll, x - cnt1 * a[i]) + c[i] - 1) / c[i];
        res = min(res, cnt1 * b[i] + cnt2 * d[i]);
        cnt1--;
        k++;
    }
    return res;
}
bool chk(ll mid) {
    ll res = 0;
    for (int i = 1; i <= n; i++) res += get(i, mid);
    return res <= X;
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> X;
    for (int i = 1; i <= n; i++) cin >> a[i] >> b[i] >> c[i] >> d[i];
    ll l = 0, r = 1e9;
    while(l < r) {
        ll mid = (l + r + 1) / 2;
        if(chk(mid)) l = mid;
        else r = mid - 1;
    }
    cout << l;
    return 0;
}

标签:10,cnt,int,题解,ll,mid,物品,ABC374E
From: https://www.cnblogs.com/Running-a-way/p/18448870

相关文章

  • P10678 『STA - R6』月 题解
    Solution看了别的大佬的题解,感觉都是数学证明然后用树和图做的,看不懂啊。。。萌新瑟瑟发抖用vector模拟树,然后贪心摸索做出来了。注意到要求最深叶子结点和最浅叶子结点的距离最短时的情况,那么此时根节点应该是树中度数最大的点,把树尽可能的拓宽,深度换宽度。那么同理的根节点......
  • 题解:P11008 『STA - R7』异或生成序列
    Solution序列\(p\)是\(1\)~\(n\)的排列,因此考虑搜索回溯。由\(\sumn\le2\times10^6\)得知\(O(n^2)\)会炸,深感遗憾但仍考虑剪枝。坚信深搜过百万的蒟蒻。。。原\(b\)序列为长度\(n-1\)的序列:{\(b_1,b_2,b_3\cdotsb_n-1\)}将其前面插入一个元素\(......
  • 题解:AT_abc374_d [ABC374D] Laser Marking
    看到\(n\le6\),就知道这道题又是一道搜索了。题面有点长,信息也给的有点多,但稍微分析就可以得到只需要搜索印刷线段的顺序即可。具体的,我们在深搜函数里面传\(4\)个参数,分别代表已选线段的数量,当前位置的横纵坐标,以及当前时间。为了方便,我们表示的是已经印刷完当前线段后的时间......
  • P5593 题解
    题目分析首先考虑什么样的颜色能被链覆盖。容易想到当某种颜色恰巧在一条链上会被覆盖。所以只需要判断一种颜色是否能构成链即可,链的贡献也很好计算。算法考虑链的性质:有且仅有两个端点。凭借这个性质,可以判断一种颜色是否在一条链上。在dfs中考虑各种情况。假设一个......
  • P10418 [蓝桥杯 2023 国 A] 相连的边 题解
    一个比较有趣的树形DP,情况比较多。【题目简述】给定一棵树,求三条相连的边,其边权之和最大。【思路】以X代表当前节点,S表示儿子,G表示孙子,P表示父节点。首先把树建出来,在以下图中,我们模拟二号点的DP过程,考虑以下几种情况:有一条边指向父节点时FG(FatherGrandson):一......
  • 数列 题解
    题意给出一张联通图,图上每个点有红蓝两色,给每一条边都赋一个权值,使得所有的红边构成一颗最小生成树,且权值是\(1\)到\(m\)的排列,求字典序最小的情况。题解对于一条蓝边,其权值一定小于除它以外全是红边的环上的所有红边的权值(有点绕),否则就构不成一颗生成树。所以只需要按顺......
  • CF946G Almost Increasing Array 题解
    题目传送门前置知识最长不下降子序列|权值树状数组及应用解法若将\(\{a\}\)变成严格递增序列,至少需要更改\(n\)减去\(\{a_{i}-i\}\)的最长不下降子序列长度个数。证明对于\(a_{i},a_{j}(i<j)\)若都在最终的严格递增序列里,则有\(a_{i}-a_{j}\lei-j\),即\(......
  • PHP报错getimagesize(): SSL operation failed with code 1问题解决方案
    这个PHP错误通常发生在尝试通过HTTPS协议获取图像时,由于缺少或过期的CA证书导致SSL连接验证失败。以下是详细的解决方案:解决方案一:更新CA证书下载最新的CA证书访问 curl官方提供的CA证书 页面下载 cacert.pem 文件。上传证书文件将下载的 cacert.......
  • U486684 「INOI2016」Brackets 题解
    首先对于回文&括号有一个经典转移:枚举分割点+区间两个端点讨论此题也是如此首先枚举分割点十分套路,如下\[dp_{i,j}=\max_{k=i}^{j-1}dp_{i,k}+dp_{k+1,j}\]如果两个端点相同\[dp_{i,j}=dp_{i+1,j-1}+v_i+v_j\]还有一个转移对于一个区间,因为是子序列,所以一个区间的子区间......
  • qoj9230 Routing K-Codes 题解
    首先这个图肯定不能有环,也不能有度数大于\(3\)的点。也就是说这是一颗二叉树。我们假设父亲都比儿子小,根节点的值最小。那么假设\(u\)点的值为\(x\),它的儿子的值一定是\(\{2x,2x+1\}\)的子集。会发现\(u\)的子树内的权值和是一个关于\(x\)的一次函数。而且无论两个儿......