题目:有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?
类似于前面写到的LSI最长递增子序列,
只不过这里控制了选取K个,
所以这里定义了一个最大数据结构fm[i][j] 其中表示选取了i+1个学生,以j结束(选取了j为结尾)最大值
这里数组可能有负数,所以定义了一个最小数据结构fn[i][j]
迭代的数据结构:
fm[k][i]
=
max
(fm[k][i],
max
(fm[k
-
1
][j]
*
arr[i], fn[k
-
1
][j]
*
arr[i]))
fn[k][i]
=
min
(fn[k][i],
min
(fm[k
-
1
][j]
*
arr[i], fn[k
-
1
][j]
*
arr[i]))
代码如下:
n
=
int
(
raw_input
())
arr
=
map
(
int
,
raw_input
().split())
K,D
=
map
(
int
,
raw_input
().split())
fm
=
[ ([
0
]
*
n)
for
i
in
range
(K) ]
# k*d
fn
=
[ ([
0
]
*
n)
for
i
in
range
(K) ]
# k*d
res
=
0
for
i
in
range
(n):
fm[
0
][i]
=
arr[i]
fn[
0
][i]
=
arr[i]
for
i
in
range
(n):
for
k
in
range
(
1
,K):
#for j in range(i-1,-1,-1):
for
j
in
range
(i
-
1
,
max
(
0
,i
-
D)
-
1
,
-
1
):
#if (i-j<D and k>0):
fm[k][i]
=
max
(fm[k][i],
max
(fm[k
-
1
][j]
*
arr[i], fn[k
-
1
][j]
*
arr[i]))
fn[k][i]
=
min
(fn[k][i],
min
(fm[k
-
1
][j]
*
arr[i], fn[k
-
1
][j]
*
arr[i]))
#fm[k][i] = max(fm[0][i],max(fm[k-1][j]*arr[i], fn[k-1][j]*arr[i]))
#fn[k][i] = min(fn[0][i],min(fm[k-1][j]*arr[i], fn[k-1][j]*arr[i]))
#fm[k][i] = max(fm[k-1][j]*arr[i], fn[k-1][j]*arr[i])
#fn[k][i] = min(fm[k-1][j]*arr[i], fn[k-1][j]*arr[i])
res
=
max
(res,fm[K
-
1
][i])
print
res