牛客练习赛 59 c 装备合成
链接:https://ac.nowcoder.com/acm/contest/4743/C
来源:牛客网
题目描述:
牛牛有x件材料a和y件材料b,用2件材料a和3件材料b可以合成一件装备,用4件材料a和1件材料b也可以合成一件装备。牛牛想要最大化合成的装备的数量,于是牛牛找来了你帮忙。
输入描述:
输入包含t组数据
第一行一个整数t
接下来t行每行两个整数x,y
输出描述:
每组数据输出一行一个整数表示答案。
朴素做法:
发现 三件甲和一件乙,共花费10件x, 10件b,所以可以通过这个去凑,最后朴素枚举当x、y不够10件的情况
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a, b, t;
int main()
{
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &a, &b);
int ansa = 0, ansb = 0;
if (a >= b)
{
int t = min(b, (a - b) / 3);
b -= t, a -= t << 2;
ansb = t + b / 10, ansa = b / 10 * 3;
a -= b / 10 * 10, b %= 10;
}
else
{
int t = min(a >> 1, b - a);
b -= 3 * t, a -= t << 1;
ansb = a / 10, ansa = t + a / 10 * 3;
b -= (a / 10) * 10, a %= 10;
}
if (a >= 4 && b > 0)
{
int t = min(a >> 2, b);
ansb += t, a -= t << 2, b -= t;
}
if (a >= 2 && b >= 3)
{
int t = min(a >> 1, b / 3);
ansa += t, a -= t << 1, b -= t * 3;
}
if (b == 0)
while (ansa && a >= 6)
{
--ansa, a += 2, b += 3;
int t = min(a >> 2, b);
ansb += t, a -= t << 2, b -= t;
}
else if (b)
while (ansb && b >= 5)
{
--ansb, b += 1, a += 4;
int t = min(a >> 1, b / 3);
ansa += t, a -= t << 1, b -= t * 3;
}
printf("%d", ansa + ansb);
if (t) puts("");
}
return 0;
}
三分做法:
假设做n件甲,那么做$min(\frac{x - 2 * n}{4},y - 3 * n)$件乙
总件数$all = n + min(\frac{x - 2 * n}{4},y - 3 * n)$,求all的最大值
一般的就是把n枚举,但是从题目x,y<=1e9
n=[0,min(x/2,y/3)]——即完全不做甲 ->完全做甲,时间复杂度是1e9/2
所以我们要用三分缩小n的范围,然后在范围内枚举n
把all看出是关于自变量n的函数,$all=n+min(\frac{x - 2 * n}{4},y - 3 * n)$,
三分用之前一定要验证函数是$\wedge$或$\vee$或或单增或单减的函数,即h(x)'在范围内最多一个零点
然而想一下,x、y差不多的时候($\wedge$), x远远大于y的时候(单增),y远远大于x的时候(单减)
每次看两个三分之一点哪个更小,更小的更新为边界
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int a, b, t;
int is(int n)
{
return n + min((a - 2 * n) >> 2, b - 3 * n);
}
int main()
{
scanf("%d", &t);
for (int i=0;i<t;i++)
{
scanf("%d%d", &a, &b);
int l = 0, r = min(a / 2, b / 3);
while (r - l > 3)
{
int m1 = l + (r - l) / 3, m2 = r - (r - l) / 3;
if (is(m1) > is(m2)) r = m2;
else l = m1;
}
int ans = 0;
while (l <= r) ans = max(ans, is(l++));
printf("%d\n", ans);
}
return 0;
}

浙公网安备 33010602011771号