字节笔试
第三题
n 行数据:
该需求所需天数di, 延期该需求需要请ci杯奶茶
3 4
1 100
2 2
5 5
要求输出最少奶茶顺序:
2 1 3 4
import functools
class Node:
def __init__(self,index,day,cost):
self.i = index
self.d = day
self.c = cost
def cmpare(x, y):
if x.d * y.c > x.c * y.d:
return 1
if x.d * y.c < x.c * y.d:
return -1
return 0
x = int(input())
for _ in range(x):
n = int(input())
nums = []
for i in range(n):
day, cost = input().split()
nums.append(Node(i + 1,int(day), int(cost)))
nums.sort(key = functools.cmp_to_key(cmpare))
for node in nums:
print(node.i, end = ' ')
print()
利用cmp函数进行排序之间相乘最大的排最前面
第四题
优美数列:
满足 Ai = Ai-1 * Ai-2 mod 2021
求一组数中优美数列组数和最长长度
n = int(input())
nums = [int(num) for num in input().split()]
dp = [[0] * 2021 for i in range(n)]
f = [[0] * 2021 for i in range(n)]
count = [[0] * 2021 for i in range(n)]
for i in range(n):
for j in range(i - 1, -1 ,-1):
dp[i][nums[i] * nums[j] % 2021] = 2
f[i][nums[i] * nums[j] % 2021] += 1
for i in range(n):
for j in range(i - 1, -1 ,-1):
if dp[j][nums[i]]:
dp[i][nums[i] * nums[j] % 2021] = max(dp[i][nums[i] * nums[j] % 2021], dp[j][nums[i]] + 1)
if dp[i][nums[i] * nums[j] % 2021] == dp[j][nums[i]] + 1:
if dp[j][nums[i]] == 2:
count[i][nums[i] * nums[j] % 2021] += f[j][nums[i]]
else:
count[i][nums[i] * nums[j] % 2021] += count[j][nums[i]]
max_len = max(max(dp))
if max_len == 2:
print(0)
print(0)
cnt = 0
for row in range(n):
for col in range(2021):
if dp[row][col] == max_len:
print(row,col)
cnt += count[row][col]
print(max_len)
print(cnt)
思路:
动态规划
-
维护两个二维数组,第一个维度为数字长度,第二个维度为2021.
-
对于这两个dp数组,我们从头遍历,j 小于当前index,每个dp 保存当前位置i的最大路径(下一个位置为0 ~ 2020)由第二个维度决定,
dp[i][nums[i] * nums[j] % 2021] = 2
,我们对小于当前 index的所有j遍历赋值,这相当于前两个为j ,i 第三个数为nums[i] * nums[j] % 2021时的路径初始化为2(因为当前在i还没到第三个数) -
对于count数组,保存当前位置对应数(0 ~ 2020)的路径数,每次初始化遇到时加一
-
然后进行动态规划:i从头遍历,j 从头遍历到小于i处,如果存在从j到i的路径,进行更新取大,如果更新,则计数count也加上前面的路径