2016-11-25 24 views
0

我們有一系列項目1,...,n,每個項目都有一個分數(i)。如果我們選擇一個項目,那麼我們不能選擇i + 1,... i + rest(i)項。目標是最大化總分。以最大增益順序跳轉 - 動態編程

我們可以用動態規劃解決這個問題。

對於第一項我們有兩個選項。或選擇它並轉到其餘(1)+ 1項目或不選擇它並轉到第二項目。

的遞歸函數:

c[i] = max{ c[i - 1], c[i + rest(i) + 1] + score(i) } 

與此遞歸函數的問題是,它的子問題意味着子問題之間創建週期不是獨立的。

我認爲這將是理想的有類似

c[i] = max{ c[i - 1], c[i - itemThatWentToItem(i)] + score(i) } 

也許一個解決辦法是有一個功能,讓所有導致項目我,然後把它們之間的最大比分的項目。

另一個想法是將此問題轉換爲DAG中的最長路徑,並針對所有子圖執行此操作。

任何想法?

+0

從端計算它:C [1] = MAX {C [1 + 1],C [1 +其餘(ⅰ)+ 1] +評分(i)} – Ante

+0

愚蠢的問題,但我可以在遞歸函數中做到這一點?最後的解決方案是c [0]? – Laxmana

回答

1

除了註釋。是的,它可以用遞歸來實現,這樣的:

def C(i, n): 
    if i > n: 
    return 0 
    return max(C(i+1, n), C(i+rest(i)+1)+score(i)) 
print C(0,n) 

這是最好的(最快)來計算從後面值。像(注:陣列被索引1到n):

# initialize array with lot of zeros: length + max score(i) 
cs = [0] * (n+max(rest(i) for i in range(0,n)+1) 
for i in range(n, 0, -1): 
    cs[i] = max(cs[i+1], cs[i+rest(i)+1]+score(i)) 
print cs[1] 
+0

謝謝!知道我理解得更好。我認爲從理論/數學的角度來看,你無法從最終計算出來。沒有理由爲什麼:)。 – Laxmana

+0

一般來說,在遞歸函數中,我可以去c [i - 1]或c [i + 1](取決於問題),對吧? – Laxmana

+1

想法是通過解決更簡單的類似子問題來解決問題。在這種情況下,最簡單的子問題是最後一個元素,因爲它不影響其他任何元素,只有一個組合。然後,最後兩個元素,有兩個組合...因此,從後面解決它更容易。 – Ante