冶炼金属【暴力枚举 + 二分 + 二元不等式】

这篇具有很好参考价值的文章主要介绍了冶炼金属【暴力枚举 + 二分 + 二元不等式】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

😊😊 😊😊
不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质
😊😊 😊😊

[蓝桥杯 2023 省 B] 冶炼金属

题目描述

小蓝有一个神奇的炉子用于将普通金属 O 冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V V V V V V 是一个正整数,这意味着消耗 V V V 个普通金属 O 恰好可以冶炼出一个特殊金属 X,当普通金属 O 的数目不足 V V V 时,无法继续冶炼。

现在给出了 N N N 条冶炼记录,每条记录中包含两个整数 A A A B B B,这表示本次投入了 A A A 个普通金属 O,最终冶炼出了 B B B 个特殊金属 X。每条记录都是独立的,这意味着上一次没消耗完的普通金属 O 不会累加到下一次的冶炼当中。

根据这 N N N 条冶炼记录,请你推测出转换率 V V V 的最小值和最大值分别可能是多少,题目保证评测数据不存在无解的情况。

输入格式

第一行一个整数 N N N,表示冶炼记录的数目。

接下来输入 N N N 行,每行两个整数 A , B A,B A,B,含义如题目所述。

输出格式

输出两个整数,分别表示 V V V 可能的最小值和最大值,中间用空格分开。

样例 #1

样例输入 #1

3
75 3
53 2
59 2

样例输出 #1

20 25

提示

【样例说明】

V = 20 V=20 V=20 时,有: ⌊ 75 20 ⌋ = 3 , ⌊ 53 20 ⌋ = 2 , ⌊ 59 20 ⌋ = 2 \left\lfloor\frac{75}{20}\right\rfloor=3,\left\lfloor\frac{53}{20}\right\rfloor=2,\left\lfloor\frac{59}{20}\right\rfloor=2 2075=3,2053=2,2059=2,可以看到符合所有冶炼记录。

V = 25 V=25 V=25 时,有: ⌊ 75 25 ⌋ = 3 , ⌊ 53 25 ⌋ = 2 , ⌊ 59 25 ⌋ = 2 \left\lfloor\frac{75}{25}\right\rfloor=3,\left\lfloor\frac{53}{25}\right\rfloor=2,\left\lfloor\frac{59}{25}\right\rfloor=2 2575=3,2553=2,2559=2,可以看到符合所有冶炼记录。

且再也找不到比 20 20 20 更小或者比 25 25 25 更大的符合条件的 V V V 值了。

【评测用例规模与约定】

对于 30 % 30 \% 30% 的评测用例, 1 ≤ N ≤ 1 0 2 1 \leq N \leq 10^{2} 1N102

对于 60 % 60 \% 60% 的评测用例, 1 ≤ N ≤ 1 0 3 1 \leq N \leq 10^{3} 1N103

对于 100 % 100 \% 100% 的评测用例, 1 ≤ N ≤ 1 0 4 1 \leq N \leq 10^{4} 1N104 1 ≤ B ≤ A ≤ 1 0 9 1 \leq B \leq A \leq 10^{9} 1BA109

蓝桥杯 2023 省赛 B 组 C 题。

小白到进阶各种解法:

一、暴力枚举:😊

思路:

简化问题 :不要一上来就分析多条记录,而是分析一条记录,找出问题的本质;

分析题目性质:

1、A个O生成B个X,我们要求A个O恰好生成B个X的转化率,转化率分为最大转化个数 m a x V max_V maxV 和 最小转化个数 m i n V min_V minV

m i n V min_V minV:表示 A 个 O A个O AO 恰好生成 B 个 X B个X BX 的所需的最小消耗值;
m a x V max_V maxV:表示 A 个 O A个O AO 恰好生成 B 个 X B个X BX 的所需的最大消耗值;

2、所求转化率必须是能够使 A个O恰好能生成B个X;不能多一个X也不能少一个X;也就是说:max_V 和 min_V都要能使得A个O恰好生成B个X。

3、 A / V = = B A/V == B A/V==B 该公式随着 V V V 的增大而减少!可看作是单调递减的!
冶炼金属【暴力枚举 + 二分 + 二元不等式】

问题:

1、如何求:A个O恰好能生成B个X所需要的最大转化个数 max_V 和 最小转化个数 min_V 呢?

答: 可以直接循环暴力枚举V,从 V = 1 V=1 V=1 开始,但是有同学会问:那么循环到什么时候结束呢?首先 V V V 是将 A 个 O A个O AO 转化为 B 个 X B个X BX,假如 V > A V > A V>A,那还能转化吗?很明显是不能了,所以 V V V 的最大枚举到 A A A 即可!

循环体内部:判断 A / V = B A / V = B A/V=B 如果等于的话,则分别与 m a x V max_V maxV m i n V min_V minV 取最值。若不等于的话,则枚举下一个 V V V ;当

加个优化: i f ( A / V < B ) if (A/V < B) if(A/V<B) 则由于随着 V V V 的增大, A / V A/V A/V的值单调递减,所以若往后继续枚举的话, A / V A/V A/V 的值将永远不会再大于 B B B了! 而 V V V 从1开始枚举的时候,是最大的, A / 1 , A / 2 , A / 3 , , , A/1,A/2,A/3,,, A/1A/2A/3,,, 所以这时候可以直接 b r e a k break break
冶炼金属【暴力枚举 + 二分 + 二元不等式】
时间复杂度:由于 需要循环枚举的是 V V V V V V 的枚举范围取决于 A A A,而 A A A 的最大值是: 1 e 9 1e9 1e9,所以很容易超时,故该算法超时!

部分代码:针对一条记录而言:

int a, b;
	cin >> a >> b;
	int min_v = inf;
	int max_v = 0;
	for (int v=1; v <= a; v ++)
	{
		if (a/v == b) {
			min_v = min(min_v, v);
			max_v = max(max_v, v);
		}
		
		if (a/v < b) {
			break;
		}
	}

针对多条记录:
而本题要求的是:多条记录,即你的两个 V V V 求出来要满足每条记录的 A 个 O A个O AO 恰好生成 B 个 X B个X BX
直接一图胜千言吧:批注:该图在下文二分里面也会用到:
冶炼金属【暴力枚举 + 二分 + 二元不等式】

假设当前是三条记录的话:那么我们要找的是一个公共的 V V V 值,能同时满足三条记录的最小转化值和最大转化值!!!!

而公共最小值的话:就是从最小值集合里面: [ m i n V 1 , m i n V 2 , m i n V 3 ] [min_V1,min_V2,min_V3] [minV1minV2minV3] 中挑选出最大的那个,对于 m a x V max_V maxV 也是同理!

这也是本题所求解的核心,就是叫你去求解这个!!!!!
结论:最小值里选取最大值,最大值里面选取最小值!

代码:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
int n;
const int inf = 0x3f3f3f3f;
int Min_V=0, Max_V=inf;

int main()
{
	cin >> n;
	
	while (n --)
	{
		int a, b;
		cin >> a >> b;
		int min_v = inf;
		int max_v = 0;
		for (int v=1; v <= a; v ++)
		{
			if (a/v == b) {
				min_v = min(min_v, v);
				max_v = max(max_v, v);
			}
			
			if (a/v < b) {
				break;
			}
		}
		//该条记录的最小转化值和最大转化值取完了以后再与公共的最大转化值和最小转化值进行取最值!
		Min_V = max(Min_V, min_v);
		Max_V = min(Max_V, max_v);
	}
	
	cout << Min_V << " " << Max_V << endl;
	
	return 0;
} 

冶炼金属【暴力枚举 + 二分 + 二元不等式】

冶炼金属【暴力枚举 + 二分 + 二元不等式】

二、二分优化:😊

思路:结论:最小值里选取最大值,最大值里面选取最小值!

首先思考上面的代码里面超时的代码部分是在哪里?显然外层循环的 n n n 组数据是改变不了的,而内存里面的 f o r for for 循环将会超时,由于查找的 V V V 的范围过大而产生超时,所以说我们应该优化的是这里!而内层 f o r for for 循环所做的事情是:一个一个 V V V 地去枚举,由于枚举次数过多而超时!所以我们可以试着去减少枚举的次数!

注意上面暴力枚举思路里面的一句话,是使用二分的关键!
m i n V min_V minV:表示 A 个 O A个O AO 恰好生成 B 个 X B个X BX 的所需的最小消耗值;
m a x V max_V maxV:表示 A 个 O A个O AO 恰好生成 B 个 X B个X BX 的所需的最大消耗值;

从这句话里面我们可以看出有 m i n V min_V minV m a x V max_V maxV 之间必然也有一段 V V V 是能够使得 A 个 O A个O AO 恰好能生成 B 个 X B个X BX 的情况!

冶炼金属【暴力枚举 + 二分 + 二元不等式】

简化问题:依然是从一条记录开始分析。
这里再简化一下:因为我们是每消耗 V V V O O O 转化成一个 X X X V V V 的个数越少,消耗越少,越省钱,所以先求:要用 A 个 O A个O AO 恰好生产 B 个 X B个X BX的最小消耗的 V V V 的个数是多少?
如下图所示:
绿色部分表示: A / V > = B A/V >= B A/V>=B 的,合法但是不完全精确!
红色部分表示: A / V < B A/V < B A/V<B 的,表示完全不合法!
紫色部分表示: A / V = = B A/V == B A/V==B 的,是合法区域的值!
冶炼金属【暴力枚举 + 二分 + 二元不等式】
所以说最后要找的是:大绿色框框里面的部分:
冶炼金属【暴力枚举 + 二分 + 二元不等式】
开启上帝视角的话,找的应该是: V = = 5 V==5 V==5 这个值!即绿色和紫色的交界处:
冶炼金属【暴力枚举 + 二分 + 二元不等式】


那么对于数字 5 的查找就很 e a s y easy easy 了,直接将问题转化为找到第一个大于等于 5 的元素即可。
部分代码:即找到最小值!建议先不看这里

if (A/V <= B) R = mid;
else L = mid;

冶炼金属【暴力枚举 + 二分 + 二元不等式】

初始化: L = 0 , R = A + 1 , m i d = L + R > > 1 ; L = 0, R = A+1,mid = L+R >> 1; L=0R=A+1mid=L+R>>1;
如果 A / m i d < = B A/mid <= B A/mid<=B 则说明此时的 V V V 过大了,则移动右指针 R R R 使得 V V V值的范围变下,则下次再取 V V V 值的时候也必然变小,因为: L + R > > 1 = = m i d = = V L+R >> 1 ==mid ==V L+R>>1==mid==V R R R变小则 V V V 变小! L L L 变大,则 V V V也变大!

如果 A / m i d > B A/mid > B A/mid>B 则说明此时的 m i d 也就是 V mid也就是V mid也就是V V V V 偏小了但是合法,我们想看看当前这个 V V V 是否是恰好使得 A / m i d 恰好 = B A/mid 恰好= B A/mid恰好=B 的最小的 V V V,因为当前的 V V V 我们并不确定它是否是 恰好等于 的关系,所以说,我们还需要往右试探比当前这个 V V V 更大的 V V V 来看是否合法,如果比当前的 V V V 更小,并且 A / V > = B A/V >= B A/V>=B 则说明这个解更优!而如何枚举到比当前 V V V 更大的V呢?经过上段的分析可知:调整我们的 L L L 即可,使得它变大,所以此时应该执行的操作是: L = m i d L = mid L=mid


而接下来就是找 使得 A/mid == B 的最大V

建议先不看,自己推一遍,用:A=75 B=3 进行一遍模拟!
if (A/mid >= B) L = mid;		
else R = mid;	这种情况也就是:A/V >= B 的情况!!!!

此种情况下,二分的边界值为最大的 V V V ,能够使得 A 个 O A个O AO 恰好转化为 B 个 X B个X BX 的最大转化值 V = = 7 V == 7 V==7!即找到下图的紫色框框里最靠右边的值!
冶炼金属【暴力枚举 + 二分 + 二元不等式】

对于这两段代码的选取:
找大于等于某个数的最左边的一个值:
关键是 i f ( < = ) if(<=) if(<=) 里面的 <= 号!这样理解,如果你要找的是大于等于某个数最左边的值,那么就 <= 箭头朝左,加个等于号!

if (A/V <= B) R = mid;
else L = mid;

找大于等于某个数的最右边的一个值:
关键是 i f ( > = ) if(>=) if(>=) 里面的 >= 号!这样理解,如果你要找的是大于等于某个数最右边的值,那么就 >= 箭头朝右,加个等于号!

if (A/mid >= B) L = mid;		
else R = mid;	这种情况也就是:A/V >= B 的情况!!!!

如果是多条记录的话:
就是找最小值里面的最大值咯,比较每条记录的最小值,找最大的那个最小值 M i n V Min_V MinV,而该值一定能够满足每条记录都恰好转化出 B 个 X B个X BX

就是找最大值里面的最小值咯,比较每条记录的最大值,找最小的那个最大值 M a x V Max_V MaxV,而该值一定能够满足每条记录都恰好转化出 B 个 X B个X BX
一图胜千言!
冶炼金属【暴力枚举 + 二分 + 二元不等式】
结论:最小值里选取最大值,最大值里面选取最小值!

代码:

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;
const int inf = 0x3f3f3f3f;
int n;		//n组数据! 
int Min_v=0, Max_v=inf;	//分别存储最小值集合里面最大的最小值,最大值集合里面的最小的最大值! 

int main()
{
	cin >> n;
	
	while (n --)
	{
		int a, b;
		cin >> a >> b;
		
		//找能够使得 A个O 恰好转化为 B个X的最小转化值! 
		int l=0, r=a+1;
		while (l + 1 != r)
		{
			int v = l + r >> 1;
			if (a/v <= b) r = v;		//找最小值的最大值,则是 <=,即找到合法区域里的左边界! 
			else l = v;
		}
		
		Min_v = max(Min_v, r);
		
		//找能够使得 A个O 恰好转化为 B个X的最大转化值! 
		l=0, r=a+1;
		while (l + 1 != r)
		{
			int v = l + r >> 1;
			if (a/v >= b) l = v;		//找最大值里的最小值,就是 >= 即找合法区域的右边界! 
			else r = v;
		}
		Max_v = min(Max_v, l);
	}
	
	cout << Min_v << " " << Max_v << endl;
	return 0;
}

冶炼金属【暴力枚举 + 二分 + 二元不等式】

冶炼金属【暴力枚举 + 二分 + 二元不等式】
每个人都有一个觉醒期,但觉醒期的早晚决定个人的命运。

三、二元不等式😊

代码:



冶炼金属【暴力枚举 + 二分 + 二元不等式】

每个人都有一个觉醒期,但觉醒期的早晚决定个人的命运。文章来源地址https://www.toymoban.com/news/detail-432028.html

到了这里,关于冶炼金属【暴力枚举 + 二分 + 二元不等式】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 各种数学不等式

    以丹麦技术大学数学家约翰·延森(John Jensen)命名。它给出积分的凸函数值和凸函数的积分值间的关系。 是数学家柯西(Cauchy)在研究数学分析中的“流数”问题时得到的。 是柯西不等式的推广. 赫尔德不等式是数学分析的一条不等式,取名自奥图·赫尔德(Otto Hölder) 是德国

    2024年02月14日
    浏览(32)
  • Hoeffing不等式

    设 X 1 , X 2 , . . . , X N X_1,X_2,...,X_N X 1 ​ , X 2 ​ , ... , X N ​ 是独立随机变量,且 X i ∈ [ a i , b i ] , i = 1 , 2 , . . . , N ; S N = ∑ i = 1 N X i X_iin[a_i,b_i],i=1,2,...,N;S_N=sum_{i=1}^NX_i X i ​ ∈ [ a i ​ , b i ​ ] , i = 1 , 2 , ... , N ; S N ​ = ∑ i = 1 N ​ X i ​ ,则对任意t0,以下不等式成立:

    2024年02月07日
    浏览(30)
  • 不等式证明(三)

    设 p , q p ,q p , q 是大于1的常数,并且 1 p + 1 q = 1 frac{1}{p}+frac{1}{q}=1 p 1 ​ + q 1 ​ = 1 .证明:对于任意的 x 0 x0 x 0 ,有 1 p x p + 1 q ≥ x frac{1}{p}x^p+frac{1}{q}geq x p 1 ​ x p + q 1 ​ ≥ x . 证明 : 设 f ( x ) = 1 p x p + 1 q − x (1) f(x)=frac{1}{p}x^p+frac{1}{q}- xtag{1} f ( x ) = p 1 ​ x p + q 1 ​

    2024年01月21日
    浏览(35)
  • 高中数学:不等式(初接高)

    最后的例题,是为了说明第三种情况,就是,不等号右边不为0时,要先进行移项操作。 将右边化为0 这样,就转化成1,2两种情况了。 补充: 不等式解法中,对于根式的转化,要考虑仔细,不能少考虑了情况,否则求出的结果就出错。 这个,也是最难的,最考验答题人的细心

    2024年01月24日
    浏览(36)
  • 四边形不等式学习笔记

    四边形不等式是一种 dp 优化策略。多用于 2D DP。 对于区间 ([l,r]) 带来的贡献 (w(l,r)) ,如果其满足: 对于 (Lleq lleq r leq R) , (w(L,r)+w(l,R)leq w(L,R)+w(l,r)) 则称 (w) 满足 四边形不等式 。特别地,如果上式符号取等,则称其满足 四边形恒等式 。 注:上面的不等式可以记

    2023年04月10日
    浏览(36)
  • 切比雪夫(Chebyshev)不等式

    设随机变量x具有数学期望 E ( x ) = μ E(x) = mu E ( x ) = μ ,方差 D ( x ) = σ 2 D(x) = sigma^{2} D ( x ) = σ 2 。记 X ∗ = X − μ σ X^{* } =frac{X-mu }{sigma } X ∗ = σ X − μ ​ , 则X*的期望和方差为: E ( X ∗ ) = 1 σ E ( X − μ ) = 1 σ [ E ( X ) − μ ] = 0 E(X^{*})= frac{1}{sigma} E(X-mu)=frac{1}{sigma

    2024年01月16日
    浏览(35)
  • 线性矩阵不等式(LMI)(一):简单介绍

    主要从以下三个方面介绍: 什么是线性矩阵不等式(LMI) 为什么要用线性矩阵不等式(LMI) 线性矩阵不等式的发展(控制系统中) 1. 线性矩阵不等式 如名字所示线性矩阵不等式三要素为: 线性 - 注意双线性时,LMI不好求解(非凸问题);例:在不等式中出现 P A K PAK P A K 形式,其

    2024年01月20日
    浏览(32)
  • 切比雪夫不等式,大数定律及极限定理。

    1.定理 若随机变量X的期望EX和方差DX存在,则对任意ε 0,有    P{ |X - EX| = ε } = DX/ε 2 或 P{ |X - EX| ε } = 1 - DX/ε 2 2.解析定理 ①该定理对 X 服从什么分布不做要求,仅EX DX存在即可。 ②“| |” 由于X某次试验结果可能大于期望值,也可能小于期望值,但总在其旁边波动,所 以加

    2024年02月06日
    浏览(49)
  • 不等式约束二次规划——有效集法

    这个其实很好理解,通过以下两张图片就可以很清晰的明白这句画的意思: 黑色箭头是约束的区域,蓝色五角星是是全局最优点。对于左边的图,最优点在不等式范围之内,但是这个最优点有没有这个约束都可以求出来,所以这个约束可以看成无效的约束,也就是加不加这个

    2024年02月04日
    浏览(32)
  • 冯诺依曼(Von Neumann)迹不等式证明

    假设 A ∈ S + + n mathbf{A} in {mathbb{S}_{++}^n} A ∈ S + + n ​ , B ∈ S + + n mathbf{B} in {mathbb{S}_{++}^n} B ∈ S + + n ​ ,其特征值分别为: λ 1 ( A ) ≥ λ 2 ( A ) ≥ ⋯ ≥ λ n ( A ) 0 , λ 1 ( B ) ≥ λ 2 ( B ) ≥ ⋯ ≥ λ n ( B ) 0 lambda_1(mathbf{A}) geq lambda_2(mathbf{A}) geq cdots geq lambda_n(mathbf

    2024年02月14日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包