题目描述:
Alice 是 n
个花园的园丁,她想通过种花,最大化她所有花园的总美丽值。
给你一个下标从 0 开始大小为 n
的整数数组 flowers
,其中 flowers[i]
是第 i
个花园里已经种的花的数目。已经种了的花 不能 移走。同时给你 newFlowers
,表示 Alice 额外可以种花的 最大数目 。同时给你的还有整数 target
,full
和 partial
。
如果一个花园有 至少 target
朵花,那么这个花园称为 完善的 ,花园的 总美丽值 为以下分数之 和 :
- 完善 花园数目乘以
full
. - 剩余 不完善 花园里,花的 最少数目 乘以
partial
。如果没有不完善花园,那么这一部分的值为0
。
请你返回 Alice 种最多 newFlowers
朵花以后,能得到的 最大 总美丽值。
代码思路:
-
限制花朵数量:首先,将每个花园的花朵数量限制在
target
以内,因为超过target
的花朵数量对结果没有额外贡献。 -
排序:将花园按花朵数量降序排序,以便优先考虑花朵数量最多的花园。
-
检查是否所有花园都能成为完善花园:如果通过添加
newFlowers
可以将所有花园都变为完善花园,则直接返回最大可能美丽值full * n
。 -
前缀和与指针:
- 使用
prefix_sum
来记录当前花园之前所有花园的花朵总数(用于计算将前i
个花园补至target
所需的花朵数量)。 - 使用指针
j
来标记当前考虑作为部分花园的最小花朵数量的花园。
- 使用
-
遍历花园:
- 对于每个花园,如果它已经是完善花园,则跳过。
- 计算将前
i
个花园补至target
所需的花朵数量need
。 - 如果剩余花朵数量不足,则退出循环。
- 调整指针
j
,确保剩余花朵数量可以均匀分配到剩余花园。 - 计算剩余花园在均匀分配花朵后的最小值
min_flowers
。 - 更新最大美丽值
ans
。
代码实现细节
- 限制花朵数量:
flowers[i] = min(flowers[i], target)
- 排序:
flowers.sort(reverse=True)
- 前缀和与指针:使用
prefix_sum
和j
来计算和标记。 - 遍历与计算:通过遍历每个花园,计算将其变为完善花园或部分花园所需的花朵数量,并更新最大美丽值。
返回值:
返回最大可能的总美丽值。
代码实现:
class Solution:
def maximumBeauty(self, flowers: List[int], newFlowers: int, target: int, full: int, partial: int) -> int:
n = len(flowers)
ans = 0
# 将每个花园的花数限制在 target 以内
for i in range(n):
flowers[i] = min(flowers[i], target)
# 降序排序
flowers.sort(reverse=True)
# 计算所有花园的总花数
total_flowers = sum(flowers)
# 如果所有花园都能成为完善花园,初始化
if (target * n) - total_flowers <= newFlowers:
ans = full * n
prefix_sum = 0 # 前缀和,用于计算前 i 个花园的总花数
j = 0 # 指针,用于计算剩余花园的最小值
for i in range(n):
if i != 0:
prefix_sum += flowers[i - 1]
# 如果当前花园已完善,跳过
if flowers[i] == target:
continue
# 计算将前 i 个花园补至 target 所需的花数
need = newFlowers - (target * i - prefix_sum)
# 如果剩余花数不足,退出循环
if need < 0:
break
# 调整指针,确保剩余花数能够均匀分配到剩余花园
while not (j >= i and flowers[j] * (n - j) - total_flowers <= need):
total_flowers -= flowers[j]
j += 1
# 计算剩余花数均匀分配后的最小值
need -= flowers[j] * (n - j) - total_flowers
min_flowers = min(flowers[j] + need // (n - j), target - 1)
# 更新最大值
ans = max(ans, full * i + partial * min_flowers)
return ans