問題の量が増加すると、より多くのモデルを見ます
ダイナミックプログラミング、状態の明確な定義、明確なシフト、明確な境界線(境界が転送より時々より重要です)
だから、タイトル、「スティックを切る」、私は$さdp $の範囲を見ていないが、私は突然、紫色の本に疑問を覚え始めより
それについて考え、この質問とほぼ同じ
初めに、私は[I、J] $ $ I $の$ jは$最小コストをエンドポイント間を発現するF $を定義し、$ K $切断点を列挙する
持っています
$$ F [I、J] = \ underset {I <K <J} {分} \左\ {F [I、K] + F [K、J] \右\} +([J] -a [I] +1)-1 $$
しかし、以下に示すように偶然の一致は、$転送F $を発生し、この定義、
定義を変更するので、$ F [私は、j]は$は表し$ $ I $最小コスト$ J(を含むないと$ I $ $ $ J)
持っています
$$ F [I、J] = \ underset {I <K <J} {分} \左\ {F [I、K] + F [K、J] \右\} +([J] -a [I] -1)-1 $$
以下に示すように、これは権利であります
コードは以下の通りです
1の#include <iostreamの> 2の#include <cstdioを> 3の#include <アルゴリズム> 4の#include <CStringの> 5 の#define LL長いロング 6 // の#include <積層> 7 使って 名前空間STD。 8 9テンプレート<型名T> 空隙 内(T&X){ 10 、X = 0。T F = 1。チャー CH = GETCHAR()。 11 ながら(!isdigit(CH)){ 場合(CH == ' - ')、F = - 1; CH = GETCHAR();} 12 ながら(isdigit(CH)){X = 10 * X + CH - ' 0 '。CH = GETCHAR();} 13 X * = F。 14 } 15 // --------------------------------------------- --------------- 16 17 のconst int型 N = 105 。 18 19 のint M、N、F [N]、[N] [N]。 20 21 のint DP(int型 I、int型のJ){ 22 INT&_f = F [I] [J]。 23 もし(_f)を返す_f。 24 // もし(I == j)は0を返します。 25 もし(I + 1 == j)に戻り 0 。 26 INT TMP = 0x3f3f3f3f 。 27 のための(int型 K = I + 1、K <= J- 1 TMP =分(TMP、DP(I、K)+; ++ K)DP(K、J))。 28 リターン _f = TMP + [J] -a [I] - 2。// -2 29 } 30 31 INT メイン(){ 32 freopenは(" 0.in "、" R " 、STDIN)。 33 中(M); 中(N) 34 のために(int型 I = 1 ; I ++; iが<= N)で([I])。 35 ソート(A + 1、+ N + 1)。[ 0 ] = 0 ; A [N + 1 ] = M + 1。// 0、M + 1つの 36 // のmemset(F、0x3fを、はsizeof(F))。 37 COUT << DP(0、N + 1 )。 38 リターン 0 ; 39 }