知识点:位运算,树上倍增
T3 使子序列和等于目标数的最少操作数
构造法。因为相加不需要操作,所以从低位到高位,依次拼凑。
class Solution:
def minOperations(self, nums: List[int], target: int) -> int:
if sum(nums) < target:
return -1
# 统计每种2的幂出现的次数
cnt = [0] * 32
for num in nums:
for i in range(32):
if num & (1 << i):
cnt[i] += 1
break
# target 转成二进制保存在数组中
tar = [0] * 32
k = target
for i in range(32):
tar[i] = k % 2
k = k // 2
s = 0
op = 0
for i in range(32):
if tar[i]:
if s >= (1 << i):
s -= (1 << i)
elif cnt[i]:
cnt[i] -= 1
else:
j = i
while True:
if cnt[j]:
cnt[j] -= 1
break
j += 1
for x in range(i, j):
cnt[x] += 1
op += 1
s += cnt[i] * (1 << i)
return op
T4 在传球游戏中最大化函数值
方法一:树上倍增
方法二:内向基环树
感想。数的二进制表示,多项式。