(蘭練習DPは、その後、午前午後のqwqからそれをドラッグします)
この質問はまた、その後、典型的な間隔DPです。それはネックレスなので、リングはとても明確に、そして我々は、n個のノードのリングを入れて、同じ統合石に続くことができる拡張2 * Nノードのチェーンとなっています。最後のノードが最初のノードのヘッドマークをマーキング2 * N =尾であることに留意されたいです。
次いで、DPの通常の動作範囲次のとおり列挙インターバル長、Iは一緒に重合いくつかのエネルギービーズの列挙です。
列挙は、次に点を左:右端は2 * Nの範囲を超えないことを確保しつつ。
右側のエンドポイントを定義します。J =は+ NUM-1;
次の列挙ブレーク。
列挙より重要なブレークポイントは、私から列挙されたブレークポイントは〜J-1、(我々はまた、言葉を繰り返し計算Fを理解していない、なぜ私たちが知らない[i]の[j]のとき、時刻k = j)は
转移方程:F [I] [J] = MAX(F [I] [J]、[I] [K] + F [K + 1]〜[J] +ヘッド[i]は*尾[K] *尾F [J])。
これは石1の最初のスタック〜kがマージされたスタックであるので、その後のk + 1〜j個の石がスタックにまとめ、私は〜jのように組み合わせて重ね、2つのビードは、以下のようになります。
、所以+ヘッド[I] *尾[K] *尾[J]。
そして、最後に列挙(何点ブレークに列挙相当)は、最大値を見つけます。
コード:
#include <ビット/ STDC ++ H> 使用して名前空間STDを、 インラインint型リード(){ int型 ANS = 0 。 チャー最後= ' '、CH = GETCHAR()。 一方、(CH> ' 9 ' || CH < ' 0 ')最後= CH、CH = GETCHAR()。 一方、(CH> = ' 0 ' && CH <= ' 9 ')ANS =(ANS << 1)+(ANS << 3)+ CH- ' 0 '、CH = GETCHAR()。 もし (最後== ' - ')ANS = - ANS。 戻るANSを。 } INT N; int型のヘッド[ 202 ]、尾[ 202 ]。 INT [F 202 ] [ 202 ]。 INT (){メイン N = 読み取ります()。 以下のために(int型 i = 1 ; iが<= N; iは++ ) ヘッド[I] (リード。=)、ヘッド[iがN +] = ヘッドを[I]。 以下のために(int型 i = 1 ; iは= < 2 * N- 1 ; iは++ ) 尾を[I] =頭部[I + 1 ]。 尾[ 2 * N] =ヘッド[ 1 ]。 用(int型 NUM = 2 ; NUM <= N; NUM ++ ){ ため(int型 iは= 1 ; I + num- 1 <= 2 * N; iは++ ){ int型 J = + num- 1 。 用(int型 K = I; K <= J- 1 ; ++ k個) F [i]は[J] = MAX(F [I] [J]、[I] [K] + F [K + F 1 ] [J] +ヘッド[I] *尾[K] * 尾[J])。 } } int型ANS = 0 ; 以下のために(int型 I = 1 ANS = MAX(ANS、F [i]は[I + N-iが++; = n iは<)1 ])。 coutの << ANS << てendl; リターン 0 ; }
終わり-