王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅 无
如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
请你帮助王强设计一个满足要求的购物单。
def order_tune(a,min_m):
j=0
#调整列表顺序,将附件放到对应主件的后面
for item in a:
if item[2]!=0:
a[item[2]-1].extend(item)
else:
if item[0]<min_m:
min_m=item[0]
j+=1 #判断有几个主件
b=[]
for item in a:
if len(item)==3 and item[2]==0:
b.append(item)
elif len(item)>3:
for i in range(len(item)//3):
b.append(item[3*i:3*i+3])
return b,j,min_m
def arr_get(a,num):
v=[[0 for _ in range(4)] for _ in range(num)] #money矩阵
w=[[0 for _ in range(4)] for _ in range(num)] #weights矩阵
m=-1 #第几个主件
k=0#用来判断附件个数
for i in range(len(a)):
a[i][0]=a[i][0]//10
if a[i][2]==0:
m+=1
k=0
main=a[i][0]
weight=a[i][0]*a[i][1]
v[m][0]=main
w[m][0]=weight
else:
k+=1
if k==1: #1个附件
aux1=a[i][0]
weight1=a[i][0]*a[i][1]
v[m][1]=main+aux1
w[m][1]=weight+weight1
else: #2个附件
aux2=a[i][0]
weight2=a[i][0]*a[i][1]
v[m][2]=main+aux2
w[m][2]=weight+weight2
v[m][3]=main+aux1+aux2
w[m][3]=weight+weight1+weight2
return v,w
n,m=map(int,input().strip().split())
a=[]
for i in range(m):
item = list(map(int,input().strip().split()))
a.append(item)
min_m=n
a,num,min_m=order_tune(a,min_m)
#num:主件种类,min_m:购买一个主件最少需要花费多少钱
v,w=arr_get(a,num)
#v:每一种主件与其附件的组合构成的钱数数组,
#w:每一种主件与其附件的组合构成的钱数*重要性数组
weights=[0]*(n//10+1)
for i in range(len(v)):
for k in range(n//10,min_m//10-1,-1):
for j in range(4):
if k>=v[i][j]:
weights[k]=max(weights[k],weights[k-v[i][j]]+w[i][j])
print(weights[-1]*10)
2020.4刚做第一遍的时候参考了牛客网陀螺酱做法,这一次在之前基础上完善修改之后,更加直观明了。
欢迎灌水。
1.https://www.nowcoder.com/profile/479266942/codeBookDetail?submissionId=65570380
2.https://www.nowcoder.com/profile/618300658/codeBookDetail?submissionId=86425486