华为机试背包问题c语言,华为机试-动态规划题

1.购物单

主件 附件

电脑 打印机,扫描仪

书柜 图书

书桌 台灯,文具

工作椅 无

如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 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 ] 。(其中 * 为乘号)

请你帮助王强设计一个满足要求的购物单。

输入的第 1 行,为两个正整数,用一个空格隔开:N m

(其中 N ( <32000 )表示总钱数, m ( <60 )为希望购买物品的个数。)

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q

(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 ~ 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)

输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值( <200000 )。

按照条件遍历的0-1背包问题

N,m=map(int,input().split())

primary={}

annx={}

for i in range(1,m+1):

v,p,q=map(int,input().split())

if q==0:

primary[i]=[v,p]

else:

if q in annx:

annx[q].append([v,p])

else:

annx[q]=[[v,p]]

w=[[]]

v=[[]]

m=len(primary) #update m

for key in primary:

w_temp,v_temp=[],[]

w_temp.append(primary[key][0])

v_temp.append(primary[key][0]*primary[key][1]) #p

if key in annx:

w_temp.append(w_temp[0]+annx[key][0][0]) #p+1

v_temp.append(v_temp[0]+annx[key][0][0]*annx[key][0][1])

if len(annx[key])>1:

w_temp.append(w_temp[0]+annx[key][1][0]) #p+2

v_temp.append(v_temp[0]+annx[key][1][0]*annx[key][1][1])

w_temp.append(w_temp[0]+annx[key][0][0]+annx[key][1][0]) #p+1+2

v_temp.append(v_temp[0]+annx[key][0][0]*annx[key][0][1]+annx[key][1][0]*annx[key][1][1])

w.append(w_temp)

v.append(v_temp)

dp=[[0]*(N+1) for _ in range(m+1)]

for i in range(1,m+1):

for j in range(1,N+1):

max_i=dp[i-1][j]

for k in range(len(w[i])):

if w[i][k]<=j:

max_i=max(max_i,dp[i-1][j-w[i][k]]+v[i][k])

dp[i][j]=max_i

print(dp[-1][-1])

2.放苹果

题目描述

把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。

输入

每个用例包含二个整数M和N。0<=m<=10,1<=n<=10。

样例输入

7 3

样例输出

8

使用递归或者动态规划

def cal(m,n):

if m<0 or n<0:

return 0

elif m==1 or n==1:

return 1

else:

return cal(m,n-1)+cal(m-n,n)

while True:

try:

m,n=map(int,input().split())

print(cal(m,n))

except:

break

dp的算法还有点问题

def cal(m,n):

dp=[[0]*(n+1) for _ in range(m+1)]

for k in range(1,m+1):

dp[k][1]=1

for k in range(1,n+1):

dp[1][k]=1

for i in range(2,m+1):

for j in range(2,n+2):

dp[i][j]=dp[i][j-1]+(0 if i>=j else dp[i-j][j])

return dp[m][n]

while True:

try:

m,n=map(int,input().split())

print(cal(m,n))

except:

break

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值