コンテスト2.3運動のプログラミング課題:格安回文POJ - 3280

ファーマージョンはそれを自動化するシステムをインストールしているように、すべての牛のトラックを保つことは難しい作業をすることができます。彼は、それぞれの牛に牛をスキャナで通過するシステムが読み込まれます、電子IDタグを設置しました。各IDタグの内容は、現在の長さの単一の文字列である  M  (1≤  M  のアルファベットから引き出さ≤2,000)文字  N  (1≤  N  ≤26)異なる記号(すなわち、小文字アルファベット)。

牛は、彼らはいたずらな生き物であること、時には逆方向に歩いてシステムを偽装してみてください。そのIDである牛が「ABCBAは」彼女は「ABCB」IDで、牛を歩く方向に関係なく同じ読みだろうが、潜在的に2つの異なるID(「ABCB」と「bcba」)として登録することができます。

FJは、彼らが牛がで歩く方向と同じノー事項を読むように、牛のIDタグを変更したいと思います。例えば、「ABCBは」形成する「」末尾に追加することによって変更することができる「ABCBA」はIDがパリンドロームであるように(後方同じ前方とを読み出します)。パリンドロームするIDを変更するには、いくつかの他の方法には、IDを生成するために初め「bcbabcb」に3つの文字「BCB」を追加したり、文字「」IDを生成する「BCB」を除去することを含むされています。一つは、長い文字列または元の文字列よりも短いが得られた文字列内の任意の場所に文字を追加または削除することができます。

残念ながら、IDタグとして各文字の挿入または欠失は、コスト(0≤有し、電子ている  コスト  ≤10,000)追加または削除されるべき正確どの文字値に応じて変化します。牛のIDタグの内容と挿入やアルファベットの文字のそれぞれを削除するコストを考えると、それを満たすFJの要件ので、IDタグを変更するには、最小コストを見つけます。空のIDタグは、同じ前後を読んでの要件を満たすために考えられています。関連するコストとの唯一の文字が文字列に追加することができます。

入力

1行目:2つのスペースで区切られた整数:  N  および  M
2行目:この行は、正確に含まれている  M  初期のID列を構成する文字
行を3 ..  N 2:入力アルファベットの文字:各行は3スペースで区切られたエンティティが含まれていますそれぞれその文字の追加と削除のコストで二つの整数。

出力

行1:指定された名前タグを変更する最小コストである単一の整数を持つ単一行。

サンプル入力

3 4 
ABCB 
1000~1100 
B 350 700 
C 200 800

サンプル出力

900

ヒント

私たちは「」最後に「ABCBA」を取得するために挿入した場合、我々は「BCB」を挿入した場合「」「BCB」を得るために最初に、コストは1100になります削除した場合、コストは1000になります文字列の初めに、コストが最小となる、350 + 200 + 350 = 900であろう。
タイトル、ルック無知な力を得るために、二人は無知な力に直面しています。あなたがたのDPああ?この質問は、実際に私たちは小さなから大きなダイナミックソルバーに、2に、要素文字列から始まることができます。具体的な方法はあるようです。
私たちは、DPは、[i] [j]はJ列パリンドローム最小コストに私から変更されたと仮定します。
それはまた、お金を必要としない場合は1を、私たちは回文を開始するには1つの文字から文字列を取得するのは簡単になり、文字が2、回文である必要がありますが、ない場合は、前または文字の後のいずれかの選択肢を持っています、我々は同様に、各文字のコストに読むかもしれないので、回文となり、できるもう一方の端の文字の前または後に追加または文字を削除されて動作することは、コストを取ることです追加または削除するには良い決定であり、最小のストレージの間で。
最後の文字が等しくない場合、新しい文字、最初の文字を追加するときに2は、新たに追加された文字を追加する必要があり、削除したり、新しい文字列が動作する最初または最後の操作で追加することによって、特に、パリンドロームであります1は、効果は同じであったと述べたように、プロセス1は非常に重要ですので、追加または削除され安い参照してください。
最後の文字が同じである場合、新しい文字、最初の文字を追加すると、それは文字列の先端に最初の文字の文字からのDP値に対応し、実際に包括的に動作しないことを意味3、(新しい文字列と同じと最後あなたは、選択した方法が必ず2つの以上の修正文字であれば、動作する必要が無駄に多くのお金を費やすことはありません。
する#include <stdio.hに> 
する#include <iostreamの> 
する#include <アルゴリズム> 
する#include < 文字列・H>
 使用して 名前空間STD;
 チャー A [ 2005 ];
 int型 hashs [ 30 ]; //文字最小コストマッピング
 INT DP [ 2005 ] [ 2005 ];所望のパリンドロームにサブストリングの他の文字の文字から//組成物は、かかる
 INTメイン(ボイド
{ 
    int型、追加、デル
     チャーCを、
     INT N-をM; 
    scanfの(" %Dの%のD "、およびN-、&M)。
    scanf関数(" %のS " 、A)
     のためのINT I = 0 ;私は<N- I ++ 
    { 
        一方が(scanf関数(" %のC "!、&C)&&(C <= ' Z ' && C> = ' A ' ))
        {} 
        scanfの(" %D%D "、アド・、・デル); //コスト削除又は追加される端部で算出された読み込ま
        hashs [C - ' A ' ] = 分(ADD、デル)を、
    } 
    のためのINT I = 1; I <M、I ++ 端位置差に)// Iの平均開始位置
         のためのINT J = 0 ; I <M + J; J ++ )// J手段その文字列の開始位置
        { 
            IF( [J] == [J + I])//我々はjに必要としないことを+ 1〜J IまたはJ〜J + I + - 1列パリンドロームコストにあるため、必要な文字のような過充電本来不要動作
                DP [J] [J + I] DP = [J + 1 ] [J + I - 1 ]; //どうか== JまたはI + 1 == Jその後、J + 1> J I + - 1 値は、理論的に持つべきではないが、我々はデフォルトで0に初期化されているので、使用していることをそう。
            
                DP [J] [J + I] =分(DP [J + 1 ] [J + I] + hashs [A [J] - [ A ' ]、DP [J] [J + I - 1 ] + hashs [A [I + J] - [ A' ]); //最初または最後の運用コストaの新しい文字列を取得
        } 
    のprintf(" %のD \ N- "、DP [ 0 ] [M - 1。]); //最初から元の文字列を最後の一から一は、これのサブ文字列(実際には、元の文字列である)最小コスト列パリンドロームとなる
     戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/jacobfun/p/12229149.html