卡牌
问题描述
这天, 小明在整理他的卡牌。
他一共有nnn种卡牌,第i种卡牌上印有正整数数i(i∈[1,n]),i(i∈[1, n]),i(i∈[1,n]),且第i种卡牌现有aaa张。
而如果有nnn张卡牌,其中每种卡牌各一张,那么这nnn张卡牌可以被称为一套牌。小明为了凑出尽可能多套牌,拿出了mmm张空白牌,他可以在上面写上数i,i,i,将其当做第i种牌来凑出套牌。然而小明觉得手写的牌不太美观,决定第iii种牌最多手写bbb张。
请问小明最多能凑出多少套牌?
输入格式
输入共3行,第一行为两个正整数n,m。n, m。n,m。
第二行为nnn个正整数a1,a2,...,an。a_1, a_2,.. . ,a_n 。a1,a2,...,an。
第三行为nnn个正整数b1,b2,...,bn。b_1, b_2,. . . , b_n 。b1,b2,...,bn。
输出格式
一行,一个整数表示答案。
样例输入
4 5
1 2 3 4
5 5 5 5
样例输出
3
样例说明
这 5 张空白牌中, 拿 2 张写 1 , 拿 1 张写 2 , 这样每种牌的牌数就变为了 3,3,3,4 可以凑出 3 套牌, 剩下 2 张空白牌不能再帮助小明凑出一套。
评测用例规模与约定
对于303030%的数据,保证n≤2000;n ≤2000;n≤2000;
对于100100100%的数据,保证n≤2×105;ai,bi≤2n;m≤n2。n≤2 × 10^5; a_i,b_i≤ 2n; m ≤n^2。n≤2×105;ai,bi≤2n;m≤n2。
运行限制
最大运行时间:1s
最大运行内存:512M
思路分析:
根据题意分析我们可以得出当前题目是让我们求出最大值。
由数据范围为 2×1052×10^52×105可知,暴力是不可行的,暴力n2n^2n2,直接会超时。
求最大值,我们可以想到使用二分来做,二分时间复杂度O(log2N)O(log_2N)O(log2N),不会超时。
二分:
- mid = 当前最多的套牌数量。
- check函数:
根据题意我们可以发现
mid - 当前牌的数量 = 当前牌需要手写的卡牌数 = 当前牌需要的空白牌数
①枚举每张牌,如果当前牌的数量大于 midmidmid,那么就跳过这张牌。
②如果 midmidmid −-− 当前牌的数量 >>> 当前牌可以手写的卡牌数,那么可以发现mid 一定大了,我们就把 r=mid−1。r = mid - 1。r=mid−1。
③如果当前空白牌的数量 <<< midmidmid −-− 当前牌的数量,那么可以发现mid还是大了,我们就把 r=mid−1。r = mid - 1。r=mid−1。
④否则就把 l=midl = midl=mid 直到 l=rl = rl=r
代码:
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
typedef long long LL;
LL n, m;
struct c
{
LL a, b;
} p[N];
bool check(int mid)
{
LL ans = m; // 空白牌
for (int i = 1; i <= n; i ++ )
{
if(p[i].a > mid) continue; // 如果当前卡牌的张数 > 目前的最多卡牌数,就不用考虑。
if(mid - p[i].a > p[i].b) return 0;
// 目前最多的卡牌数 - 当前卡牌的张数 = 达到目前最多卡牌数所需要的手写牌的数量。
// 如果当前卡牌所能手写的牌数 < 达到目前最多卡牌数所需要的手写牌的数量,那么就可以得出:目前最多卡牌数大了。
ans -= mid - p[i].a; // 如果空白牌 < 达到目前最多卡牌数所需要的手写牌的数量,那么就可以得出:空白牌数量少了,目前最多卡牌数大了。
if(ans < 0) return 0;
}
return 1;
}
int main()
{
// 请在此输入您的代码
cin >> n >> m;
for (int i = 1; i <= n; i ++ ) cin >> p[i].a;
for (int i = 1; i <= n; i ++ ) cin >> p[i].b;
int l = 0, r = 2 * n;
while (l < r)
{
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << r << endl;
return 0;
}
该问题是一个关于卡牌组合的问题,小明试图用现有的卡牌和空白牌凑出尽可能多的完整套牌。给定每种卡牌的数量和可手写的最大张数,需要找出最大套牌数。通过二分搜索方法,检查在每个中间值下是否能凑出完整的套牌,从而找到最大值。
883

被折叠的 条评论
为什么被折叠?



