題目描述
有 n 個學生站成一排,每個學生有一個能力值,牛牛想從這 n 個學生中按照順序選取 k 名學生,要求相鄰兩個學生的位置編號的差不超過 d,使得這 k 個學生的能力值的乘積最大,你能返回最大的乘積嗎?
輸入描述:
每個輸入包含 1 個測試用例。每個測試數據的第一行包含一個整數 n (1 <= n <= 50),表示學生的個數,接下來的一行,包含 n 個整數,按順序表示每個學生的能力值 ai(-50 <= ai <= 50)。接下來的一行包含兩個整數,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
輸出描述:
輸出一行表示最大的乘積。
示例1
輸入
3
7 4 7
2 50
輸出
49
解題參考:http://blog.csdn.net/fcxxzux/article/details/52138964
解題思路及代碼:
原理類似於迭代求解函數,考慮k=1作爲初始點,來推斷k=2時的結果,其中需要注意負負得正。
# f [ i ] [ j ] [ 0 / 1 ]表示,總人數爲j,以第i個人爲最後一個人,乘積的最大值和最小值。
# 考慮到負負得正,所以需要保留負數中的最小值。
# 通過公式f[i][j]=max(fm[k][j-1]*stu[j],fn[k][j-1]*stu[j]),可以一次遍歷得出結果
n = int(input())
# 與版本2不同,python3中,map函數返回一個map對象,而不是list,需要轉換;
# http://www.cnblogs.com/GatsbyNewton/p/4784049.html
array = list(map(int,input().split()))
k,d = map(int,input().split())
# 初始化三維數組(大小),由內到外
resArray = [[[0] * 2 for j in range(k+1)] for i in range(n)]
result = 0;
# i表示最後一個數位於array數組位置下標i處,j表示當前乘積的數字個數,0、1分別記錄最大值和最小值
# 遍歷個數和位置
for i in range(0,n):
# 當乘積個數爲1時,結果爲當前這個數。
resArray[i][1][0],resArray[i][1][1]=array[i],array[i]
for j in range(2,k+1):
# 考慮間隔d
for m in range(max(i-d,0),i):
resArray[i][j][0] = max(resArray[i][j][0]
,max(resArray[m][j-1][0]*array[i],resArray[m][j-1][1]*array[i]))
resArray[i][j][1] = min(resArray[i][j][1]
,min(resArray[m][j-1][0]*array[i],resArray[m][j-1][1]*array[i]))
result = max(result,max(resArray[i][k][0],resArray[i][k][0]))
print(result)