間隔DP
質問の意味:
あなたは、元の分析になるでしょうように、n個の文字があることを特徴とする請求長さm、のあなたの文字列は、各文字は、2つの値、すなわち、この文字のコストが挿入され、文字の文字列を削除するコストを持っています最小コスト文字列回文に。
M <= 2000
提供DP [i] [j]は区間I〜Jの最小コスト回文配列であります
今私は〜jの間隔に他の国からどのように移転を検討
三つの例
最初STR [I] == STR [J]次にDP [I] [j]はDPを= [I + 1] [J-1]
次いで、(I + 1)〜Jパリンドローム配列のDPである[I] [J] = DP [I + 1] [J] +(/デル[STR [I]] [[I] STR]を追加)
最後に、I〜(J-1)はパリンドローム配列のDPである[I] [j]はDPを= [I]、[J-1] +([STR [J]] /デル[STR [j]を]追加)
コード:
1の#include <cmath> 2の#include <cstdioを> 3の#include <CStringの> 4の#include <cstdlib> 5の#include <iostreamの> 6の#include <アルゴリズム> 7 の#define APARTプット( "------ ---------------」) 8 の#define 1つのデバッグ 9 の#defineファイルテスト1 10 の#define INF 2010 11 の#defineが長い長いっ 12 の#define HA 998244353 13 の#define 0x7FFFFFFFでINF 14 #定義 INF_T 9223372036854775807 15 の#defineをDEBUGのprintf( "%sの%D \ n"は、__ FUNCTION __、__ LINE__) 16 17 名前空間チノ{ 18 19インラインボイド設定(){ 20 の#ifファイルテスト 21 freopenは(" _test.in "、" R " 、STDIN)。 22 freopenは(" _test.me.out "、" W " 、STDOUT)。 23 #endifの 24 のリターン。 25 } 26 27インラインint型リード(){ 28 CHARC = GETCHAR()、最大= C。int型 NUM = 0 ; 29 のために(; C < ' 0 ' || C> ' 9 ' ;最大= C、C = GETCHAR())。 30 のために(ステップと、c> = ' 0 ' && C <= ' 9 ' ; NUM =(NUM << 3)+(NUM << 1)+(C ^ ' 0 ')、C = GETCHAR())。 31 リターン アップ== ' - '?- NUM:NUM。 INTのN、M。 35 チャーS [INF]。 36 INT 追加[INF]、デル[INF]。 37 INT DP [INF] [INF]。 38 39インラインINT (){主 40 N =(読み取り)、M = 読み取ります(); 41 のscanf(" %sの"、S + 1 )。 42 のために(int型 i = 1 ; iが<= N; iが++ ){ 43 チャー C = 0 。 44 のstd :: cinを>> C。 45 追加[C * 1 ] =読む(); 46 デル[C * 1 ] = (読み取り) 47 } 48 INT LEN = STRLEN(S + 1 )。 49 のためには、(int型 = Iを2 ; iは<= LEN; iは++ ){ 50 DPを[I] [I] = 0 ; 51 のための(int型 J = - 1 ; J; j-- ){ 52 、DP [j]は[I] = INF。 53 であれば(S [I] == S [J]) 54 DP [j]は[I] DP [J + = 1 ] [I - 1 ]。 55 DP [J] [I] = STD ::分(DP [j] [i]は、DP [J + 1 ] [I] +のstd ::分(追加[S [j] * 1 ]、デル[S [J] * 1 ]))。 56 DP [J] [I] = STD ::分(DP [j] [i]は、DP [J] [iが- 1 ] +のstd ::分(追加[S [I] * 1 ]、デル[S [I] * 1 ]))。 57 } 58 } 59 のprintf(" %d個の\ n "、DP [ 1 ] [LEN])。 60 リターン 0 ; 61 } 62 63 } // 名前空間チノ 64 65 INTメイン(){ 戻りチノ::メイン();}