链接: 2460. 对数组执行操作
按题意模拟即可。
class Solution:
def applyOperations(self, nums: List[int]) -> List[int]:
n = len(nums)
for i in range(n-1):
if nums[i] == nums[i+1]:
nums[i]*=2
nums[i+1] = 0
ans = [0]*n
t = 0
for x in nums:
if x:
ans[t] = x
t += 1
return ans
链接: 2461. 长度为 K 子数组中的最大和
class Solution:
def maximumSubarraySum(self, nums: List[int], k: int) -> int:
n = len(nums)
ans = 0
cnt = Counter()
q = deque()
s = 0
for r,v in enumerate(nums):
q.append(r)
s += v
cnt[v] += 1
while cnt[v]>1 or len(q)>k:
l = q.popleft()
cnt[nums[l]]-=1
s -= nums[l]
if len(q) == k:
ans = max(ans,s)
return ans
链接: 2462. 雇佣 K 位工人的总代价
class Solution:
def totalCost(self, costs: List[int], k: int, candidates: int) -> int:
n = len(costs)
if n == k:
return sum(costs)
from sortedcontainers import SortedSet
vis = set()
h = []
l = candidates
r = n - candidates -1
for i in range(candidates):
j = n - 1 - i
if i not in vis:
heapq.heappush(h,(costs[i],i))
vis.add(i)
if j not in vis:
heapq.heappush(h,(costs[j],j))
vis.add(j)
# h.append((costs[i],i))
# h.append((costs[j],j))
# heapq.heapify(h)
ans = 0
for _ in range(k):
v,i = heapq.heappop(h)
ans += v
if i < l and l < n:
if l not in vis:
heapq.heappush(h,(costs[l],l))
# h.add((cost[l],l))
vis.add(l)
l+=1
elif i > r and r>=0:
if r not in vis:
# h.add((cost[r],r))
heapq.heappush(h,(costs[r],r))
vis.add(r)
r -= 1
return ans
链接: 2463. 最小移动总距离
class Solution:
def minimumTotalDistance(self, robot: List[int], factory: List[List[int]]) -> int:
robot.sort()
factory.sort()
# @cache
# def f(i,j): # 前i个工厂修理前j个机器人的最小花费,ij均从1开始计数
# if j == 0: # 没有机器人了
# return 0
# pos,limit = factory[i-1]
# if i == 1:
# if limit < j:
# return inf
# else:
# return sum(abs(x-pos) for x in robot[:j])
# ans = f(i-1,j)
# s = 0
# for k in range(1,min(limit+1, j+1)):
# s += abs(pos-robot[j-k])
# ans = min(ans, s+f(i-1,j-k))
# return ans
# return f(len(factory),len(robot))
# 空间压缩dp
n = len(robot)
f = [inf] * (n+1)
f[0] = 0
pre = 0
for pos, limit in factory:
pre += limit
for j in range(min(n,pre),0,-1):
s = 0
for k in range(1,min(limit+1,j+1)):
s += abs(pos-robot[j-k])
f[j] = min(f[j],s+f[j-k])
return f[-1]
链接: 1478. 安排邮筒
class Solution:
def minDistance(self, houses: List[int], k: int) -> int:
n = len(houses)
houses.sort()
# @cache
# def get_median_cost(l,r): # 获取在[l,r]这些房子里放一个邮箱的最小代价,显然邮箱应该放在中位数(中间那个房子)上。
# m = l+(r-l+1)//2
# return sum(abs(houses[x] - houses[m]) for x in range(l,r+1))
@cache
def get_median_cost(l,r): # 获取在[l,r]这些房子里放一个邮箱的最小代价,显然邮箱应该放在中位数(中间那个房子)上。
if l == r:
return 0
if l + 2 >= r:
return houses[r] - houses[l]
return houses[r] - houses[l] + get_median_cost(l+1,r-1)
@cache
def f(i,j): # 前i个邮筒管前j个房子的代价(给前j个房子安排i个邮筒的代价)
if j == 0 or i >= j:
return 0
if i == 1:
# m = j // 2
# return sum(abs(houses[x] - houses[m]) for x in range(j))
return get_median_cost(0,j-1)
ans = f(i-1,j) # 枚举第i个邮筒管几个房子;本行指管0个
for k in range(1, j-i+2): # 这上限可以优化到j-i+1+1,因为前i-1个房子分配i-1个邮筒即可,代价是0,本邮筒继续向前没有意义。
# m = j-k+k//2
# ans = min(ans,f(i-1,j-k)+sum(abs(houses[x]-houses[m]) for x in range(j-k,j)))
ans = min(ans,f(i-1,j-k)+get_median_cost(j-k,j-1))
return ans
return f(k,len(houses))