CF1898B Milena and Admirer(贪心)

题目链接

题目大意

有一个长度为 n 的数组

做操作使这个数组不递减:

  • 把一个数分成两个数,例如:x 分为 a 和 b, x == a + b

求最小操作次数

思路

见注释

代码

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 10;
int a[N];
 
signed main()
{
	int T;
	cin >> T;
	while (T -- )
	{
		int n; cin >> n;
		for (int i = 1; i <= n; i ++ ) cin >> a[i];
		int ans = 0;
		for (int i = n - 1; i >= 1; i -- ) 
		{
			if (a[i] > a[i + 1])
			{
				int x = a[i] / a[i + 1]; //分成几个数 
				if (a[i] % a[i + 1] != 0) x ++; //如果有余数,那就多分出了一个数
				a[i]  = a[i] / x; //使分成的那几个数的最小值尽可能大,就取一下平均值
				 // 例如
				 //a[i]  = 13, a[i + 1] = 3
				 //直接除后的方法使我们知道需要分成5个数字:
				 //1, 3, 3, 3, 3
				 //但是1太小了,会影响a[i - 1] 
				 //要使它变大,就让13 / 5, 取平均值
				 //得到 2, 2, 2, 2, 2, 余3,多的3就放在最后三位
				 //即 2, 2, 3, 3, 3,
				 //因为相当于是把多的往少的匀,所以绝对不会影响到a[i + 1] ,即最大值不会超过a[i + 1] 
				ans += (x - 1);// x是分成的数的个数,x - 1就是需要的步骤数
			}
		}
		cout << ans << endl; 
	}
	return 0;
}

总结

复述一遍思路:

当前面的数比后面的数大时,就需要拆分这个数,拆成尽可能少的个数,每个数还要尽可能大,这些数取决于后一个数,当前数 除以后一个数,如果能整除,那就分为那么多个数,且是最大的,若不能,则会多分出一个数,要使它们尽可能大(最小值最大),就是要让那个余数最大,但余数肯定大不过除数,就把这个数平均分为这么多个数,多出来的就平均分配进分出来的每一个数里面,实现最大化最小值的操作。

相关推荐
学高数就犯困30 分钟前
性能优化:LRU缓存(清晰易懂带图解)
算法
xlp666hub3 小时前
Leetcode第七题:用C++解决接雨水问题
c++·leetcode
CoovallyAIHub3 小时前
CVPR 2026 | MixerCSeg:仅2.05 GFLOPs刷新四大裂缝分割基准!解耦Mamba隐式注意力,CNN+Transformer+Mamba三
深度学习·算法·计算机视觉
CoovallyAIHub4 小时前
YOLO26-Pose 深度解读:端到端架构重新设计,姿态估计凭什么跨代领先?
深度学习·算法·计算机视觉
CoovallyAIHub4 小时前
化工厂气体泄漏怎么用AI检测?30张图3D重建气体泄漏场景——美国国家实验室NeRF新研究
深度学习·算法·计算机视觉
肆忆_4 小时前
实战复盘:手写 C++ 虚拟机的高性能并行 GC (Thread Pool + Work Stealing)
c++
肆忆_4 小时前
虚函数进阶答疑:把上一篇博客评论区里最容易卡住的问题,一次追到底
c++
颜酱16 小时前
图的数据结构:从「多叉树」到存储与遍历
javascript·后端·算法
saltymilk20 小时前
使用 C++ 模拟 ShaderLanguage 的 swizzle
c++·模板元编程
zone773921 小时前
006:RAG 入门-面试官问你,RAG 为什么要切块?
后端·算法·面试