python 合唱團 網易

題目描述 
有 n 個學生站成一排,每個學生有一個能力值,牛牛想從這 n 個學生中按照順序選取 k 名學生,要求相鄰兩個學生的位置編號的差不超過 d,使得這 k 個學生的能力值的乘積最大,你能返回最大的乘積嗎?

輸入描述: 
每個輸入包含 1 個測試用例。每個測試數據的第一行包含一個整數 n (1 <= n <= 50),表示學生的個數,接下來的一行,包含 n 個整數,按順序表示每個學生的能力值 ai(-50 <= ai <= 50)。接下來的一行包含兩個整數,k 和 d (1 <= k <= 10, 1 <= d <= 50)。 
輸出描述: 
輸出一行表示最大的乘積。

示例1 
輸入


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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章