题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
inline1 = input().split(' ')
N = int(inline1[0])
m = int(inline1[1])
staffs = []
for i in range(m):
inline2 = input().split(' ')
v = int(inline2[0])
p = int(inline2[1])
q = int(inline2[2])
staffs.append([v, p, q])
primes = {}
addts = {}
staffs_dict = {}
for i, ele in enumerate(staffs):
staffs_dict[i] = ele
for k, v in staffs_dict.items():
if not v[-1]:
primes[k+1] = v[:-1]
else:
if v[-1] not in addts.keys():
addts[v[-1]] = [v[:-1]]
else:
addts[v[-1]].append(v[:-1])
dp_arr = []
for av_num in range(1, len(primes)+1):
dp_arr.append([])
for tens in range(1, N//10+1):
dp_arr[-1].append(0)
for av_num in range(len(primes)):
# print(av_num, primes)
cur_staff = primes.popitem()
idx = cur_staff[0]
cur_prime = cur_staff[1]
if idx in addts.keys():
cur_addt = addts[idx]
cur_comp = []
if len(cur_addt) == 1: # 对主从物品的多种可能组合进行建模
cur_comp = [[cur_prime[0], cur_prime[0]*cur_prime[1]],
[cur_prime[0]+cur_addt[0][0], cur_prime[0]*cur_prime[1]+cur_addt[0][0]*cur_addt[0][1]]] # [[cur_prime], [cur_prime, cur_addt[0]]]
elif len(cur_addt) == 2: # 对主从物品的多种可能组合进行建模
cur_comp = [[cur_prime[0], cur_prime[0]*cur_prime[1]],
[cur_prime[0]+cur_addt[0][0], cur_prime[0]*cur_prime[1]+cur_addt[0][0]*cur_addt[0][1]],
[cur_prime[0]+cur_addt[1][0], cur_prime[0]*cur_prime[1]+cur_addt[1][0]*cur_addt[1][1]],
[cur_prime[0]+cur_addt[0][0]+cur_addt[1][0], cur_prime[0]*cur_prime[1]+cur_addt[0][0]*cur_addt[0][1]+cur_addt[1][0]*cur_addt[1][1]]]
else:
cur_comp = [[cur_prime[0], cur_prime[0]*cur_prime[1]]]
for tens in range(N//10):
cash = (1+tens)*10
if tens > 0 and av_num > 0: # dp_arr初始化,状态转移(比较大小)从初始化状态开始,初始化状态从左、上状态获得
dp_arr[av_num][tens] = max(dp_arr[av_num][tens-1], dp_arr[av_num-1][tens]) # initialization
elif tens > 0 and av_num == 0: # dp_arr初始化,状态转移(比较大小)从初始化状态开始,初始化状态从左、上状态获得
dp_arr[av_num][tens] = dp_arr[av_num][tens-1] # initialization
elif tens == 0 and av_num > 0: # dp_arr初始化,状态转移(比较大小)从初始化状态开始,初始化状态从左、上状态获得
dp_arr[av_num][tens] = dp_arr[av_num-1][tens]
if av_num == 0:
for comp in cur_comp: # 对每一种主从组合,都进行一次01背包的状态转移
# print(comp[0], cash)
if comp[0] <= cash:
dp_arr[av_num][tens] = max(dp_arr[av_num][tens], comp[1])
else:
for comp in cur_comp: # 对每一种主从组合,都进行一次01背包的状态转移
if comp[0] == cash:
dp_arr[av_num][tens] = max(dp_arr[av_num][tens], comp[1])
elif comp[0] < cash:
dp_arr[av_num][tens] = max(dp_arr[av_num][tens], dp_arr[av_num-1][(cash-comp[0])//10-1]+comp[1])
print(dp_arr[len(primes)-1][N//10-1])
01背包问题的拓展,如果对附属品和主物品同等级对待,那么就会在加入附属品时考虑是否已加入主物品,很麻烦。附属品可以看做是对某一个物品的升级,建模为该种物品的多种可能性,在dp时对每一种可能性都进行一次01背包问题的状态转移。这样就保证了附属品的加入在主物品加入的前提之下。

滴滴公司福利 1829人发布