1. 题目来源
链接:LCP33. 蓄水
2. 题目解析
挺恶心的一道题,作为一道 Easy
卡了不知道多少队。大意了啊。
思路:
-
所有的水桶蓄水的次数都是一样的,升级水桶的次数不一样。
-
显然应该先升级水桶再蓄水。
-
本题的枚举顺序不太容易想到。
-
先枚举所有水桶蓄水的次数,因为蓄水次数都是一样的。假设蓄水
i
次,那么针对一个桶的容量v
的话,至少需要v/i
上取整。这个容量。再减去初始容量,倒推就可以得到对应水桶升级的次数。 -
每次蓄水对应一个升级水桶的总次数,枚举得到最小值。注意需要向上取整。
-
时间复杂度: O ( n 2 ) O(n^2) O(n2)。
-
空间复杂度: O ( 1 ) O(1) O(1)
主要是枚举顺序的改变让人有点猝不及防…写代码的时候还把 1e4
,当成了 1000,上去 WA
了两发…
蓄水次数都是一样的,可以枚举。而升级水桶又可以直接求得,所以造就了本题的精妙思路。且刚好是先升级水桶,再蓄水。
很不错的枚举问题。
代码:
// 逆十字的神级简洁代码
class Solution {
public:
int storeWater(vector<int>& bucket, vector<int>& vat) {
int n = vat.size();
if (*max_element(vat.begin(), vat.end()) == 0) return 0; // 全为 0 的话,等价于最大值为 0,不需要升级和蓄水
int res = 1e9;
for (int i = 1; i <= 10000; i ++ ) { // 枚举所有水桶蓄水的次数
int sum = i;
for (int j = 0; j < n; j ++ ) {
sum += max(0, (vat[j] + i - 1) / i - bucket[j]); // 倒推得到升级水桶的次数,需要减去初始容量
}
res = min(res, sum);
}
return res;
}
};