你能构造出连续值的最大数目
分析:
class Solution:
def getMaximumConsecutive(self, coins: List[int]) -> int:
sum = 0
coins.sort()
for coin in coins:
if coin > sum + 1:
return sum + 1
else:
sum += coin
return sum + 1
小Q购物
分析:
与上一题类似思路,假设前i种面额可以构成的总额为Si,现在对前i+1种面额进行分析,如果a[i+1] <= Si,则开始选择第i+1种的面额,且此时可以取到总额Si+a[i+1]。
尽量用最大的面额!
def func(a, m, n):
cur = count = i = 0
if a[0] != 1:
return -1
else:
while cur < m:
while i + 1 < n and a[i + 1] <= cur + 1:
i += 1
cur += a[i]
count += 1
return count
m, n = map(int, input().split())
a = []
for _ in range(n):
a.append(int(input()))
a.sort()
num = func(a, m, n)
print(num)
按要求补齐数组
分析:
对于正整数 x,如果区间[1,x−1] 内的所有数字都已经被覆盖,且 x 在数组中,则区间[1,2x−1] 内的所有数字也都被覆盖。
假设数字 x 缺失,则至少需要在数组中补充一个小于或等于 x 的数,才能覆盖到 x,否则无法覆盖到 x。
如果区间[1,x−1] 内的所有数字都已经被覆盖,则从贪心的角度考虑,补充 x 之后即可覆盖到 x,且满足补充的数字个数最少。在补充 x 之后,区间 [1,2x−1] 内的所有数字都被覆盖,下一个缺失的数字一定不会小于 2x。
如果当前区间是 [1,x],我们应该添加数字 x + 1,这样可以覆盖的区间为 [1,2*x+1]。如果你选择添加小于 x + 1 的数字,达到的效果肯定没这个区间大。而如果你选择添加大于 x + 1 的数字,那么会导致 x + 1 无法被覆盖。这就是贪心的思想。
class Solution:
def minPatches(self, nums: List[int], n: int) -> int:
furthest = i = ans = 0
while furthest < n:
# 可覆盖到,直接用前缀和更新区间
if i < len(nums) and nums[i] <= furthest + 1:
furthest += nums[i] # [1, furthest] -> [1, furthest + nums[i]]
i += 1
else:
# 不可覆盖到,增加一个数 furthest + 1,并用前缀和更新区间
# 如果 nums[i] > furthest + 1,说明我们必须添加一个数 x,其中 1 <= x <= furthest + 1,从贪心的角度我们应该选择 furthest + 1,这在前面已经讲过
furthest = 2 * furthest + 1 # [1, furthest] -> [1, furthest + furthest + 1]
ans += 1
return ans