链接: 5259. 计算应缴税款总额
给你一个下标从 0 开始的二维整数数组 brackets ,其中 brackets[i] = [upperi, percenti] ,表示第 i 个税级的上限是 upperi ,征收的税率为 percenti 。税级按上限 从低到高排序(在满足 0 < i < brackets.length 的前提下,upperi-1 < upperi)。
税款计算方式如下:
送分题,我写了7min,可能这就是菜吧。
class Solution:
def calculateTax(self, brackets: List[List[int]], income: int) -> float:
tax = 0
low = 0
for u,p in brackets:
x = min(income,u-low)
income -= x
low = u
# print(x,p)
tax += x * p/100
return tax
链接: 5270. 网格中的最小路径代价
给你一个下标从 0 开始的整数矩阵 grid ,矩阵大小为 m x n ,由从 0 到 m * n - 1 的不同整数组成。你可以在此矩阵中,从一个单元格移动到 下一行 的任何其他单元格。如果你位于单元格 (x, y) ,且满足 x < m - 1 ,你可以移动到 (x + 1, 0), (x + 1, 1), …, (x + 1, n - 1) 中的任何一个单元格。注意: 在最后一行中的单元格不能触发移动。
每次可能的移动都需要付出对应的代价,代价用一个下标从 0 开始的二维数组 moveCost 表示,该数组大小为 (m * n) x n ,其中 moveCost[i][j] 是从值为 i 的单元格移动到下一行第 j 列单元格的代价。从 grid 最后一行的单元格移动的代价可以忽略。
grid 一条路径的代价是:所有路径经过的单元格的 值之和 加上 所有移动的 代价之和 。从 第一行 任意单元格出发,返回到达 最后一行 任意单元格的最小路径代价。
定级Medium。
其实不难,dp每一行记录到这里的最小代价即可。我在最短路搜索上钻牛角尖了。
定义dp[i][j] 定义为到达坐标i,j的最小代价,那么dp[i][j]一定从上一行转移而来:
class Solution:
def minPathCost(self, grid: List[List[int]], moveCost: List[List[int]]) -> int:
m,n =len(grid),len(grid[0])
dp = [[0]*n for _ in range(m)]
for i in range(n):
dp[0][i] = grid[0][i]
for i in range(1,m):
for j in range(n):
dp[i][j] = min(dp[i-1][k]+moveCost[grid[i-1][k]][j]+grid[i][j] for k in range(n))
return min(dp[m-1])
链接: 5289. 公平分发饼干
给你一个整数数组 cookies ,其中 cookies[i] 表示在第 i 个零食包中的饼干数量。另给你一个整数 k 表示等待分发零食包的孩子数量,所有 零食包都需要分发。在同一个零食包中的所有饼干都必须分发给同一个孩子,不能分开。
分发的 不公平程度 定义为单个孩子在分发过程中能够获得饼干的最大总数。
定级Medium。
平均分配的题,有点像这道: 698. 划分为k个相等的子集。
但不是严格平均,一定可以分配下去。
这题规模不大,8^8,因此可以DFS搜索。
这里吐槽一下,c++不剪枝就能过。python必须剪枝。
if j>0 and child[j] == child[j-1]:
continue
# 注意一定要逆序,实测快!
for m in range(j-1,-1,-1): # 和前边某块一样长,在前边放过了,这次不放了
if child[j] == child[m]:
break
class Solution:
def distributeCookies(self, cookies: List[int], k: int) -> int:
total = sum(cookies)
n = len(cookies)
child = [0] * k
cookies.sort(reverse=True)
ans = max(cookies[0],sum(cookies[k-1:]))
def dfs(i):
nonlocal ans
if i == n:
ans = min(ans,max(child))
return
for j in range(k):
if child[j] + cookies[i] > ans:
continue
for m in range(j-1,-1,-1): # 和前边某块一样长,在前边放过了,这次不放了
if child[j] == child[m]:
break
else:
child[j] += cookies[i]
dfs(i+1)
child[j] -= cookies[i]
dfs(0)
return ans
链接: 6094. 公司命名
给你一个字符串数组 ideas 表示在公司命名过程中使用的名字列表。公司命名流程如下:
从 ideas 中选择 2 个 不同 名字,称为 ideaA 和 ideaB 。
交换 ideaA 和 ideaB 的首字母。
如果得到的两个新名字 都 不在 ideas 中,那么 ideaA ideaB(串联 ideaA 和 ideaB ,中间用一个空格分隔)是一个有效的公司名字。
否则,不是一个有效的名字。
返回 不同 且有效的公司名字的数目。
定级Hard。
比赛时没做出来,其实不应该。
用字典中套集合,统计每个字符开头后跟的后缀们。
然后枚举每个开头的组合,
实际是求他们的后缀差集的数量。
class Solution:
def distinctNames(self, ideas: List[str]) -> int:
d = defaultdict(set)
for name in ideas: d[name[0]].add(name[1:])
return sum((len(d[a]) - len(d[a] & d[b])) * (len(d[b]) - len(d[a] & d[b])) * 2 for a, b in product(d, repeat=2) if ord(a) < ord(b))