E.マーブル状圧力DP

E.ビー玉

これは、圧力dpのようなものです

効果の件名:あなたの配列を与え、1〜20の間の配列番号は、スイッチング動作の回数は、業務の隣接する最小数の隣接する二つ頼んすべて同じ番号が存在しています

[I] [j]が数J I、C [i]は、フロント操作の最小数にIは、開始表すことを示しwはDPは、[S]は、状態sにおける操作の数を表します。

ヴァル[S] [i]はiが前の操作に数、状態Sを示しています。

次にDP [TMP] =分(DP [TMP]、DP [S] + valの[S] [J])

書式#include <cstdioを> 
する#include <CStringの> 
の#include <cstdlib> 
書式#include <キュー> 
の#include < 文字列 > 
の#include <アルゴリズム> 
書式#include <iostreamの> 
の#include <マップ>
 に#define INF 0x3f3f3f3f
 の#define inf64 0x3f3f3f3f3f3f3f3f
 使用して 名前空間STD;
const  int型 MAXN = 4E5 + 10 
typedefの長い 長いLL。
ベクトル < int型 > NUM; 
[DP LL 1 << 20]、C [ 21 ]。
LL W [ 21 ] [ 21 ]、ヴァル[ 1 << 20 ] [ 21 ]。
INT VIS [ 21 ]、B [ 21 ]、[MAXN]、合計[ 21 ]。
BOOL VIT [ 21 ]。

無効審判(int型x)は{ 
    num.clear(); 
    以下のためにint型 I = 1 ; X; iが++ ){
         場合(X&1 )num.push_back(I)。
        X >> = 1 
    } 
} 

int型メイン(){
     int型 N、LEN = 0 
    scanf関数(" %のD "、&N)
    以下のためにint型 i = 1 ; iが<= N; iが++ ){ 
        scanf関数(" %dを"[I])。
        もし [++ lenが] = B(VIT [[I]]!)[i]は、
        VIT [I] = 1 
    } 
    ソート(B + 1、B + 1 + LEN)。
    以下のためにint型私= 1 ; iが<= N; iが++)[I] = LOWER_BOUND(B +1、B + 1 + LEN、[I]) - B。
    以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
        和[[I]] ++ ;
        INT J = 1 ; J <= LENあり、j ++ ){
             場合(jは[I] ==)続けます
            W [I]、[J] + = 和[J]。
        } 
    } 
    のmemset(DP、inf64、はsizeof (DP))。
    以下のためにint型 i = 1 ; iが<= N; iは++ ){ 
        C [I]+ = I - 1 - VIS [[I]]。
        VIS [[I]] ++ ; 
    } 
    のためにint型 i = 1 ; iがLEN = <; I ++)は、DP [ 1 <<(I - 1)] = C [I]を、
    以下のためにint型私= 0 ; I <(1 << LEN); iは++ ){ 
        ジャッジ(I)。
        INT J = 1 ; J <= LENあり、j ++ ){ 
            LLのXの =のC [J]。
            INT TMP = 1 <<(j - 1 )。
            もし |(I)==私は(TMP)は継続しますint型のk = 0 ; K <num.size(); ++ K)X - = W [J] [NUM [K]。
            ヴァル[I] [J] =のX。
        } 
    } 
    のためのint型 I = 0 ; iが(< 1 ; << LEN)は、i ++は{)
         のためにINT J = 1 ; J <= LEN J ++ ){
             int型 TMP1 = 1 - <<(J 1 ;)
            もし((TMP1 | I)== i)は継続しますもし(DP [I]> = inf64)続けます
            TMP1 | = I; 
            DP [TMP1] =分(DP [TMP1]、DP [I] + ヴァル[I] [J])。
        } 
    } 
    のprintf(" %LLDする\ n "、DPの[(1 << LEN) - 1 ])。
    リターン 0 ; 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/EchoZQN/p/11574052.html