質問の意味:
行のN個の石小石スタックの総数は、各Lは、最小連続スタックとすることができる、複合R積み上げ石は、消費コストをマージします
可能でない場合、スタックに組み合わさ最小コストを求め、0を出力します。
分析:
キーは、2次元配列は、これを行うには多次元、3次元配列を開くには、列挙を通じて解決することができないです。
第二の反応器へのI、Jからスタックのコスト、Xの合成スタックによって表される状態が、最小必須。
時間計算量はO(N ^ 4)です。転送状態は、このように最初の列挙、列挙して、出発点の長さ、とは終わりを知っているということです、そしてあなたがこの範囲Xヒープにマージ列挙します。スタックに結合する場合、スタックのうちLスタックからRを算出する必要がある、必要な状態であり、複数のスタックは、単に列挙分割線として、通常の間隔DP同様に、マージする場合。
実際には、この値は、マルチスタック理由の合計値を算出せずに算出パイル合成、合成演算の和が、そう合成、少なくとも二つの山の合成パイルを作るために小さなスタックにマルチスタック石である場合、そのされた場合にのみ計算されますそれは時間の束がキーです。
書式#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> 使用して 名前空間はstdを、 const int型 MAXN = 105 ; const int型 INF = 0x3f3f3f3f 。 INT [MAXN]、[MAXN]事前; int型DP [MAXN] [MAXN] [MAXN]。 INT のmain(){ int型N、L、R。 一方、(scanf関数(" %D%D%D "、&N、&L&R)!= EOF){ 事前[ 0 ] = 0 ; 以下のための(int型 I = 1; I <= N。I ++ ){ scanf関数(" %のD "、A + I)。 事前[I] = [1-事前1 ] + [I]。 } のmemset(DP、INF、はsizeof (DP))。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ DP [I] [I] [ 1 ] = 0 ; } ため(INT LEN = L; LEN <= R; LEN ++ ){ ため(int型 i = 1 ; iが<= N-LEN + 1は iが++します; {) INT J = Iがlen + 1 ; DP [I] [J] [LEN] = 0 ; [DPは、[I]は[J]が1 ]予備= [J]が-pre [I- 1 ]; } } のために(INT = LEN 2 ; LEN <= N-; LEN ++){ // 最初の列挙長さ のために(INT I = 1 ; I <= N-len- + 1 ; Iは++){ // 再列挙開始 int型 E = IがLENを+ 。1 ; のための(INT X = LEN; X> = 1 ; X - ){ // 列挙スタック数 IF(Xの== 1 ){ ため(INT J = L; J <= R&LT; J ++){ // それがスタックに結合されている場合、スタックは列挙します DPを[I]、[E] [ 1 ] =分( DP [I]、[E] [ 1 ]、DP [I]、[E] [J] +プレ[E] [I- -pre 1。]); } } 他{ ため(INT J = I; J <= E - 1。 ; J ++){ // 分割線列挙に、マルチスタックに合わせた場合 、DP [i]は[E] [ X] =分(DP [I] [E] [X]、DP [I] [J] [X- 1 ] + DP [Jの+ 1 ]、[E] [ 1。)]; } } } } } のprintf(" %d個の\ n "、DP [ 1 ] [n]を[ 1 ] == INF?0:DP [ 1 ] [n]を[ 1 ])。 } }