问答题 阅读下列说明,回答问题。
[说明]
某餐厅供应各种标准的营养套餐。假设菜单上共有n项食物m1,m2,...,mn,每项食物mi的营养价值为vi,价格为Pi,其中i=1,2…,n,套餐中每项食物至多出现一次。客人常需要一个算法来求解总价格不超过M营养价值最大的套餐。
[问题1]
下面是用动态规划策略求解该问题的伪代码,请填充其中的空缺(1)、(2)和(3)处。伪代码中的主要变量说明如下。
n:总食物项数。
v:营养价值组,下标从1~n,对应第1到第n页食物的营养价值。
p:价格数组,下标从1~n,对应第1到n项食物的价格。
M:总标准即套餐的价格不超过M。
x:解向量(数组),下标从1~n,其元素值为0或1,其中元素值为0表示对应的食物不出现在套餐中,元素值为1表示对应的食物出现在套餐中。
nv:n+1行M+1列的二维数组,其中行和列的下标均从0开始,nv[i][j]表示由前i项食物组合且价格不超过项j套餐的最大营养价值。问题最终要求的套餐的最大营养价值为nv[n][M]。伪代码如下:
MaxNutrientValue(n,v,p,M,x)
1 for i=0 to n
2 nv[i][0]=0
3 for j=1 to M
4 nv[0][j] =0
5 for i=1 to n
6 for j=1 to M
7 if j< p[i]//若食物mi不能加入到套餐中
8 nv[i] [jl =nv[i-1][j]
9 else if (1)
10 nv[i][j] =nv[i-1][j]
11 else
12 nv[i] [j] =nv[i-1][j-p[i]]+v[i]
13 j=M
14 for i=n downto 1
15 if (2)
16 x[i] =0
17 else
18 x[i] =1
19 (3)
20 return x and nv[n] [M]
[问题2]
现有5项食物, 每项食物的营养价值和价格如表9.3所示。
表9.3食物营养价值及价格表
编码 营养价值 价格
m1 200 50
m2 180 30
m3 225 45
m4 200 25
m5 50 5
若要求总价格不超过100的营养价值最大的套餐,则套餐应包含的食物有 (4) (用食物项的编码表示),对应的最大营养价值为 (5)
[问题3]
问题1中伪代码的时间复杂度为 (6) (用O符号表示)。

【正确答案】[问题1] (1)nv[i-1][j]>=nv[i-1][j-p[i]+v[i] (2)nv[i][j]==nv[i-1][j] (3)j=jp[i]
[问题2] (4) m2,m3,m4 (5)605
[问题3] (6)O(n*M)
【答案解析】[分析] 本题考查动态规划法。题目要求在n种食物中,找出x种食物,食物总价不超过M,且食物的营养价值要尽可能大,这样的问题显然要用动态规划法来将问题分解,进而简化。动态规划法的基本理念是将问题拆解为很多相同的子问题,在求解子问题时,引入一个数组,不管它们是否对最终解有用,把所有子问题的解存于该数组中,最后再从数组中将最终结果导出,这样有效地缩短了解题的时间。而在本题中伪代码正是以此方法求解,将复杂的问题分解成了很多个子问题,而子问题的求解又是建立在之前子问题的结果基础之前,nv正是用于记录子问题结果的数组。值得一提的是本题第(3)问的出题形式,形式比较新颖,但实际上非常简单,从程序循环层数即可看出复杂度。
接下来对代码进行详细