3091. 执行操作使数据元素之和大于等于 K
390场周赛 Q2 中等
给你一个正整数 k 。最初,你有一个数组 nums = [1] 。
你可以对数组执行以下 任意 操作 任意 次数(可能为零):
选择数组中的任何一个元素,然后将它的值 增加 1 。 复制数组中的任何一个元素,然后将它附加到数组的末尾。 返回使得最终数组元素之 和 大于或等于 k 所需的 最少 操作次数。
示例 1:
输入:k = 11
输出:5
解释:
可以对数组 nums = [1] 执行以下操作:
将元素的值增加 1 三次。结果数组为 nums = [4] 。
复制元素两次。结果数组为 nums = [4,4,4] 。
最终数组的和为 4 + 4 + 4 = 12 ,大于等于 k = 11 。
执行的总操作次数为 3 + 2 = 5 。
示例 2:
输入:k = 1
输出:0
解释:
原始数组的和已经大于等于 1 ,因此不需要执行操作。
提示:
题解
1 贪心
- 首先我们要明白是先
+1
更好,- (m + 1) * 2 > m * 2 + 1
所以, 我们直接枚举所有加1
的情况
但此时需要的是 额外加
和乘
的次数
不过我不明白, 为什么要分是否除得尽
, 两种情况? (OK现在明白了)
给定不等式:
求解
首先,根据不等式,可以得到
接下来,将上式改写为:
此时 均是整数, 所以要对 进行讨论
-
当 是整数时,我们可以取 ,此时 。因为 和 都是非负整数,所以我们可以选择使 最小的整数值,从而得到 。
-
当 不是整数时,因为 需要大于 , ...
- 解释不明白, 直接举例子:
- 如果
向下取整
, 则 那么 显然和原本的 冲突 - 如果
四舍五入
, 同上情况 - 如果
向上取整
, , => 显然是合法的
- 如果
- 所以需要
上取整
:
- 解释不明白, 直接举例子:
class Solution {
public:
int minOperations(int k) {
// 贪心
// 如果 乘的次数 >= 加的次数, 则使用乘法
/*
(a + 1) * (b + 1) >= k 问 a + b
b >= k / (a + 1) - 1
a + b >= k / (a + 1) - 1 + a (上取整) (a, b 是整数) // 怎么取整, 我不会
定一求一:
for (int a = 0; a < k; ++a) {
res = min(res, k / (a + 1) - 1 + a);
}
*/
int res = 1e9;
for (int a = 0; a < k; ++a) {
if (k % (a + 1)) { // 不能整除, 向上取整
res = min(res, k / (a + 1) + a);
} else { // 整除
res = min(res, k / (a + 1) - 1 + a);
}
}
return res;
}
};
即
class Solution {
public:
int minOperations(int k) {
int res = 1e9;
for (int a = 0; a < k; ++a) {
res = min(res, (int)ceil(k / (a + 1.0)) - 1 + a);
}
return res;
}
};
2 数学
class Solution {
public:
int minOperations(int k) {
double r = 2 * pow(k, 0.5) - 2;
return r - (int)r > 0 ? (int)r + 1 : r;
}
};