NOI2011ノイカーニバル(神レベルのDP)

タイトル

分析:

タイトルを取得するには、データの範囲を注意することは少なく、その点を考えるために、可能な最大DPを求めています。

難易度はできるだけ均一、そして活動やそれ以上のものとしてAB会場を割り当てる方法、です。選択されたイベントの固定数の考慮事項は、活性Bの最大数が選択されて検索します。時間が交差しないようにするためには、時間ディメンションに圧入。

アクティブ和の数のそれぞれに対応した前処理間隔[I] [J]。

定義: DP [I] [J] 1〜私は時間を示し、Aは、j番目の会議会場から選択され、Bは、会場の最大数から選択されます。

転送:セル間転送の広い範囲にわたって、列挙ブレークポイントK:NO断面が転送方法をシミュレートしていないことを確実にするために。

1.dp [K] [J] +和[K] [i]は、

会場には、いくつかのB.を残す前に、Bの全てを残し、わずか1〜Kのj番目の時間から選択されます

2.dp [K] [J-和[K] [I]]。

会場は、上記から選択されるJ-和[K] [I ] 後方から選択し、A 和[K] [I]。

だから、我々はすべての事情を考慮を完了するために、漏れないことはできません。

また、選択された必須のタイトル、プラスansss [L] [R]、Lの最大値を表す配列〜R強制的に選択された範囲を必要とする、コード転送を参照。

 

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#define INTレジスタRI
 の#define N 405
 INTの事前[N] [N]、LS [N]、V [N]、U [N]、N、L [N]、R [N]、TMP [N]を、後方[N] [N]、合計[N] [N]、ANSS [N]。
INT メイン()
{ 
    freopenは(" show.in "" R " 、STDIN)。
    freopenは(" show.out "" W " 、STDOUT)。
    int型 CNT = 0 、T; 
    scanf関数(" %のD "、&N)
    (RI I =。1 ; I <= N; ++ I){ 
        scanfの(" %のD%のD "、&​​L [I]、&R&LT [I]); 
        R&LT [I] + = L [I]、
        TMP [ ++ CNT] L = [I]、TMP [CNT ++] = R&LT [I]; 
    } 
    ソート(TMP + 1、TMPの+ 1 + CNT); 
    LS [ 1。 =] 1。 ; // 後の時点は、1から始まる列挙されているのでから出発保証
    するために(RI = I 2 ; ++; Iは= CNT < I)の
     IF(!TMPは、[I]はTMP [I-= 1 LSを[]) I] =のLS [I- 1。 ] + 1。 ; // 離散
    LS [I] = LSは[I- 1 ]。
    
    (RI i = 1 ; I <= N ++ I)
      のために(RIのJ = 1 ; J <= CNT; ++ J){
         場合(L [I] == TMP [J])のu [i]は= LS [J]。
        もし(R [I] == TMP [J])V [I] =のLS [J]。
    } 
    のt = LS [CNT]。
    (RI i = 1 ; I <= T; ++ I)
      のために(ロードアイランドJ = I; J <= T; ++ j)の
       ための(RI k = 1 ; K <= N; ++ K){
           もし(U [K]> = I && V [K] <= j)の和[I] [J] ++ ; 
    } 
    int型 INF =1000年;
     のための(I = RI 1。 ; I <= T; ++ I)
      のために(RI = J 1、J <= N-; ++ J)
      予備[I] [J] = AFT [I] [J] = - INF; 
    
    のための(I = RI 1、I <= T; ++ I)
      のために(RI J = 0 ; J <[= SUM 1 ] [I]; ++ J){
          IF(J == 0){事前[I] [J] = SUMは、[ 1 ] [i]は、続行;}
          // 時間私の前に場所を与えた私は会場A = Bのすべての前の時間0から選択された順序を初期化
         するための(RI = K 。1 ; K <= I; ++ K){ 
              プレ[I] [J]最大値=(予備[I]、[J]、プリ[K] [J] + SUM [K] [I]); // 時間k〜I Bにj番目の時刻kから選択前者は会場会場後に得られました
              IF(J> = SUM [K] [I])事前[I] [J] = MAX(予備[I]、[J]、あらかじめ[K] [J = SUM [K] [I]);
         // 選択された前時刻k jの和[k]は[I]再選択和の背面に会場[K] [i]は番目はjに一緒に玉石会場は、会場へ
        } 
    } 
    // 互いに反対シークそれは私が〜会場T、Bは、会場の数から選択され、後方Jから選択される基を表し
    ため(RI = I Tを、Iは> = 1。 ; - I)
      のために(RI J = 0 ; J <[I] = SUM [T ]; ++ J){
          IF(J == 0){AFT [I] [J] = SUM [I] [T]; 続行;}
          ため(RI T = K、K> = I; - K) { // DPから前の列挙クラスブレークポイントの更新間隔
              AFT [I] [J] = MAX(AFT [I]、[J]、AFT [K] [J] + SUM [I] [K]);
               IF(J> = SUM [I] [K])AFT [ I] [J] = MAX(AFT [I]、[J]、AFT [K] [J = SUM [I] [K]); 
        } 
    } 
      
    int型 ANS = 0 ;
     のための(I = RI 1。 ; I <= N-; I ++)はANS = MAX(ANS、分(I、予め[T] [I])); 
    のprintf(" %d個の\ N- " 、ANS);
     // ANS [L] [R&LTは]から選択される必須を表します最大数のこの間隔のLとR 
    のための(RI = K 1、K <= N; ++ K)が
      ため(RI = I U [K]; I> = 1。 ; - Iは)// 左を指すように左の拡張
      のために(RI = J V [K]; J <= T; J ++){ //右端は右に延び
          ため(RIがL = 0 ; L <= SUM [ 1 ] [I]は、L ++){ // L Aは、左から選択されていることを確認
           するために(R&LT RI = 0 ; J R&LT <= SUM [ ] [T]; R ++){ // Rから選択される右作る 
                    // 中間の全体部分 
                ANSS [K] = MAX(ANSS [K]、分(SUM [I] [J] + LをR&LTの+、予め[I] [L] + 後方[J] [R]));
                 IF(後方[J] [R] <R&LT)BREAK ; // 後方[J] [R]におけるR&LT増加が単調です減少 
                 // これは剪定の意味です:答えはもう更新されません対応する選択されたB少なすぎる会場の右側
            }
             IF(前[I] [L] <L)BREAKを ; // 同上
        }
        IF(SUM [I]、[J]> SUMの[ 1 ] [I] + SUM [J] [T])BREAK ; // AがあまりAにつながるから選択され、答えるためにBアンバランス等価を更新することができません剪定
        IF(ANSS [K]> [SUM 1。 ] [I] + SUM [J] [T])BREAK ; //は約すべてもはや列挙を感知していない答えを更新することはできませんBを与える
    } 
       
    ため( I = RI 1、Iは<= N-; ++ I)のprintf(" %Dの\のN- " 、ANSS [I]); 
} 
/ * 
10 

15 6 

13 12である

。20は17 

。1 18れる

。5 14 

18である9。

15 25 

21 16 

16 9 

。19 14 



。5 
。8 2 
。1.5 
。5.3 
。3 2 
5 3
* /
コードの表示

 

おすすめ

転載: www.cnblogs.com/mowanying/p/11514836.html