HJ16 购物单
加了一个条件,必须要有主件才能采购附件,先把主件和附件组合在一起,再按照背包法来处理
n,m = map(int,input().split())
zj = {}
fj = {}
for i in range(m):
q, v, z = map(int, input().split())
if z == 0:
id = i+ 1
zj[id] = [q, v]
else:
if z in fj:
fj[z].append([q, v])
else:
fj[z] = [[q, v]]
moy = [[]]
val = [[]]
for key in zj:
moy_temp = []
val_temp = []
moy_temp.append(zj[key][0])
val_temp.append(zj[key][0]*zj[key][1])
if key in fj:
moy_temp.append(moy_temp[0]+fj[key][0][0])
val_temp.append(val_temp[0]+fj[key][0][0]*fj[key][0][1])
if len(fj[key]) > 1:
moy_temp.append(moy_temp[0]+fj[key][1][0])
val_temp.append(val_temp[0]+fj[key][1][0]*fj[key][1][1])
moy_temp.append(moy_temp[0]+fj[key][0][0]+fj[key][1][0])
val_temp.append(val_temp[0]+fj[key][0][0]*fj[key][0][1]+fj[key][1][0]*fj[key][1][1])
moy.append(moy_temp)
val.append(val_temp)
j_num = n // 10
i_num = len(zj)
dp = [[0]*(j_num+1) for _ in range(i_num+1)]
for i in range(1, i_num+1):
for j in range(1, j_num+1):
pre_max = dp[i-1][j]
for x in range(len(moy[i])):
if j*10 - moy[i][x] >= 0:
pre_max = max(pre_max, dp[i-1][(j*10 - moy[i][x])//10]+val[i][x])
dp[i][j] = pre_max
print(dp[i_num][j_num])
加练几道吧:
dp[i][j]表示0-i里面取数加起来能不能等于j
class Solution:
def canPartition(self, nums: List[int]) -> bool:
n = len(nums)
if sum(nums) % 2 == 1:
return False
target = sum(nums) // 2
if max(nums) > target:
return False
dp = [[False] * (target+1) for _ in range(n)]
dp[0][nums[0]] = True
for i in range(1,n):
dp[i][0] = True
for j in range(1,target+1):
if j >= nums[i]:
dp[i][j] = dp[i-1][j] | dp[i-1][j-nums[i]]
else:
dp[i][j] = dp[i-1][j]
return dp[-1][-1]
转化成数组里的数可以抽出几组等于neg
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
if (sum(nums)-target) % 2 != 0 or sum(nums)-target < 0:
return 0
neg = (sum(nums)-target) // 2
n = len(nums)
dp = [[0]*(neg+1) for _ in range(n+1)]
dp[0][0] = 1
for i in range(1,n+1):
for j in range(neg+1):
if j >= nums[i-1]:
dp[i][j] = dp[i-1][j]+dp[i-1][j-nums[i-1]]
else:
dp[i][j] = dp[i-1][j]
return dp[-1][-1]