2016-11-25 5 views
0

私たちはアイテム1、...、nのシーケンスを持ち、すべてのアイテムはスコア(i)を持っています。アイテムを選択した場合、i + 1、... i + rest(i)アイテムは選択できません。目標は合計スコアを最大にすることです。最大ゲインで順にジャンプ - 動的プログラミング

これを動的プログラミングで解決できます。

最初の項目には2つのオプションがあります。またはそれを選択して残りの(1)+ 1項目に行くか、それを選択せず​​に2番目の項目に移動します。

再帰関数:

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

この再帰関数の問題点は、サブ問題は独立していないという意味のサブ問題の間のサイクルを作成することです。

私はたぶんソリューションは、アイテムiにつながるすべての項目を与え、その後、それらの間の最大のスコアを取る機能を持っているだろう

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

のようなものを持っていることが理想的であると思います。

もう1つのアイデアは、この問題をDAG内の最長パスに変更して、すべてのサブグラフに対して実行することです。

アイデア?

+0

最後から計算してください。c [i] = max {c [i + 1]、c [i + rest(i)+ 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

アイデアは、より簡単な類似のサブ問題を解くことによって問題を解決することです。この場合、最も単純なサブ問題は他の要素に影響を与えないので最後の要素であり、1つの組み合わせしか存在しない。最後の2つの要素には2つの組み合わせがあります...それで、後からそれを解決する方が簡単です。 – Ante

関連する問題