リニアDP - hdu6578古典的なDP

 初のマルチ学校のフィールド最初の質問、DPのこのタイプの前に2つの質問をした、状態遷移は、一般的に、現在の状態から押し戻されます

クラシックDPが、非常に遅い時間

/ * 
位置DP [t]を定義する[I] [ J] [K] T元の位置を表す、記入後に{0、1、2、3}最後の4つの数字が表示され
、Tの注文後、私、(T> I> J> K) プログラムjの数、kは、Tの数字の4つのオプションに応じて、取得することができる
、または4つの転送。
Tは、この位置にT-1の番号から選択される:DP [T] [I] [j]は[K] 
T位置のI番号から選択DP [T] [T-1]〜[J] [K] 
T選択されたグループjからDP [T] [T-1] [I] [K]の位置
T kの選択された位置の数:DP [T] [T- 1] [I] [J] 
列挙R [L] == Tすべての条件の+ 1、及び全ての条件は、転送のために満たされている場合だけ

、最後のプログラム番号=和{DP [N]} 
O(N4)の合計時間の複雑性。Oの一次元、空間的複雑さ(N3)を圧延
 * / 
の#include <ビット/ STDC ++ H.>
 使用して 名前空間STD;
 の#define MAXN 110
 の#define LLロングロング 
 の#define MOD 998 244 353 
DP LL [ 2 ] [MAXN] [MAXN] 【MAXN];
 int型N-、M、
 構造体ノード{
     int型のL、X。
    ノード(){} 
    ノード(int型 L、int型X):L(リットル)、X(X){} 
}。
ベクター <ノード> V [MAXN]。

インラインボイド更新(LL&、LL b)は{ =(A + B)。
    一方 A- =(A> = MOD)MOD。
} 
int型C。
ボイド解く(){ 
    C = 0 
    DP [C] [ 0 ] [ 0 ] [ 0 ] = 1 INT T = 1 ; T <= N; T ++){ 
        C ^ = 1 ;
        以下のためにint型 i = 0 ; I <= T I ++ のためのINT J = 0 ; J <= I; J ++ のためのINT K = 0 ; K <= J; ++ k個
                    DP [C] [I]を[ J] [K] = 0 ; 
        
        以下のためにint型私= 0は、私はトンを<; I ++ のためのint型 J = 0 ; J <= iであり、j ++ のためにint型K = 0 ; K <= Jあり、k ++ ){ 
                    更新(DP [C] [I] [J] [K]、DP [C ^ 1 ] [I] [J] [K])。
                    アップデート(DP [C] [T - 1 ] [J] [K]、DP [C ^ 1 ] [I] [J] [K])。
                    アップデート(DP [C] [T - 1 ] [i]は[K]、DP [C ^ 1 ] [I] [J] [K])。
                    アップデート(DP [C] [T - 1 ] [I] [J]、DP [C ^ 1 ] [I] [J] [K])。
                } 
        のためのINT p = 0 ; p <V [T] .size(); P ++){ // 枚举每个条件
            INT L = V [T] [P] .L、X = V [T] [P ]。バツ;
            以下のためにint型私= 0 ; iはTを<; I ++ のためのINT J = 0 ; J <= I; J ++ のためのINT K = 0 ; K <= J; ++ k個){
                         int型の CNT = 1 もし(I> = 1)CNT ++ もし(J> = 1)CNT ++ もし(K> = 1)CNT ++ もし(!CNT = X)DP [C] [I] [J] [K] = 0 ; 
                    } 
        }
    } 
} 

int型のmain(){
     // IOS :: sync_with_stdio(偽)。
    int型の T; cinを>> トン。
    ながら(t-- ){
         ためint型 iは= 0 iが++; I <MAXN Vを[I] .clear())。
        
        scanf関数(" %d個の%のD "、&​​N、&M)。
        以下のためにint型 I = 1 ; I <= M; iは++ ){
             int型のL、R、X。
            scanf関数(" %D%D%D "、&​​L&R&X)。
            V [R] .push_back(ノード(L、X)); 
        }
        解決する(); 
        ANS LL= 0 ;
        以下のためにint型 i = 0 ; iがN <; I ++ のためのINT J = 0 ; J <= I; J ++ のためのINT K = 0 ; K <= J; ++ k個
                    ANS + = DP [C] [I ] [J] [K]、ANS%= MOD。
        coutの << ANS << ' \ nを' ; 
    } 
}

 

おすすめ

転載: www.cnblogs.com/zsben991126/p/11330169.html