NOI2011 Noi Carnival (God-level dp)

topic

analysis:

To get the title, noting the range of data is small, and is seeking the maximum possible dp to think about that aspect.

The difficulty is, how to allocate AB venue as uniform as possible, and activities and more. A consideration of the fixed number of selected events, to find the maximum number of active B is selected. In order to make the time do not intersect, pressed into a time dimension.

Pretreatment interval corresponding to each of a number of active sum [i] [j].

Defined: DP [I] [j] 1 ~ i indicates time, A is selected from the j-th conference site, B is selected from a maximum number of venues.

Transfer: In order to ensure that no cross sections simulated transfer method: enumeration breakpoint k, over a large range of inter-cell transfer.

1.dp[ k ][ j ]+sum[ k ][ i ];

A meeting place is selected from the j-th time only 1 ~ k's, leaving behind all of B, also in front to leave some B.

2.dp[ k ][ j-sum[ k ][ i ] ];

A meeting place is selected from the foregoing j-sum [k] [i ] a, then select from the rear sum [k] [i].

So that we can not not leak to complete consideration of all the circumstances.

Also requires mandatory title selected, plus a ansss [l] [r] array representing the maximum value of l ~ r forcibly selected range, see the code transfer.

 

#include<bits/stdc++.h>
using namespace std;
#define ri register int
#define N 405
int n,l[N],r[N],tmp[N],u[N],v[N],ls[N],pre[N][N],aft[N][N],sum[N][N],anss[N];
int main()
{
    freopen("show.in","r",stdin);
    freopen("show.out","w",stdout);
    int cnt=0,t;
    scanf("%d",&n);
    for(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]; 
    } 
    Sort (tmp + . 1 , tmp + . 1 + CNT); 
    LS [ . 1 ] = . 1 ; // ! ! ! Starting from a guaranteed because later time points are enumerated starting with 1 
    for (RI = I 2 ; I <= CNT; ++ I)
     IF (! Tmp [I] = tmp [I- 1 ]) LS [ I] = LS [I- . 1 ] + . 1 ; // discretization 
    else ls[i]=ls[i-1];
    
    for(ri i=1;i<=n;++i)
     for(ri j=1;j<=cnt;++j){
        if(l[i]==tmp[j]) u[i]=ls[j];
        if(r[i]==tmp[j]) v[i]=ls[j];
    }
    t=ls[cnt];
    for(ri i=1;i<=t;++i)
     for(ri j=i;j<=t;++j)
      for(ri k=1;k<=n;++k){
          if(u[k]>=i && v[k]<=j) sum[i][j]++;
    }
    int inf=1000 ;
     for (I = RI . 1 ; I <= T; ++ I)
      for (RI = J . 1 ; J <= n-; ++ J) 
      pre [I] [J] = AFT [I] [J] = - INF; 
    
    for (I = RI . 1 ; I <= T; ++ I)
      for (RI J = 0 ; J <[= SUM . 1 ] [I]; ++ J) {
          IF (J == 0 ) { pre [i] [J] = SUM [ . 1 ] [i]; Continue ;}
          // initialize order i selected from time 0 prior to the venue a = B all gave the venue before the time i 
         for (RI = K . 1 ; K <= I; ++ K) { 
              pre [I] [J]max = (pre [I] [j], pre [k] [j] + SUM [k] [I]); // former selected from the j-th time k to time k ~ i B gave after venue A venue 
              IF (J> = SUM [K] [I]) pre [I] [J] = max (pre [I] [J], pre [K] [J- SUM [K] [I]]);
         // previous time k j-sum selected from [k] [I] a meeting place to the back of a reselection sum [k] [i] th to j a cobble together a venue to venue a 
        } 
    } 
    // the opposite of one another seek It represents a group selected from an aft j i ~ t a venue, B is selected from the number of venues 
    for (RI = I T; I> = . 1 ; - I)
      for (RI j = 0 ; j <[I] = SUM [T ]; ++ J) {
          IF (J == 0 ) {AFT [I] [J] = SUM [I] [T]; Continue ;}
          for (RI T = K; K> = I; - K) { // Previous enumeration class breakpoint update interval from the 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 ;
     for (I = RI . 1 ; I <= n-; I ++) ANS = max (ANS, min (I, pre [T] [I])); 
    the printf ( " % D \ n- " , ANS);
     // ANS [L] [R & lt] indicates a mandatory selected from l and r of this interval the maximum number 
    for (RI = K . 1 ; K <= n-; ++ K)
      for (RI = I U [K]; I> = . 1 ; - I) // to point to the left left extension 
      for (RI = J V [K]; J <= T; J ++) { //The right end extends to the right 
          for (RI l = 0 ; l <= SUM [ . 1 ] [I]; l ++) { // make a l A is selected from the left 
           for (R & lt RI = 0 ; R & lt <= SUM [J ] [T]; r ++) { // make the right a is selected from the r 
                    // whole portion of the intermediate to the a 
                ANSS [K] = max (ANSS [K], min (SUM [I] [J] + L R & lt +, pre [I] [L] + aft [j] [r]));
                 IF (aft [j] [r] <R & lt) BREAK ; // R & lt increase in aft [j] [r] is a monotonically decreasing 
                 // this is the meaning of pruning: the right of the selected B too little venue corresponding answer will no longer be updated 
            }
             IF (pre [I] [L] <L) BREAK ; // Ibid 
        }
        IF (SUM [I] [J]> SUM [ . 1 ] [I] + SUM [J] [T]) BREAK ; // A is selected from too much will lead to A, B unbalance equivalent to the answer can not be updated a pruning 
        IF (ANSS [K]> [SUM . 1 ] [I] + SUM [J] [T]) BREAK ; // about all give B can not update the answer is no longer sense the enumeration 
    } 
       
    for ( I = RI . 1 ; I <= n-; ++ I) the printf ( " % D \ n- " , ANSS [I]); 
} 
/ * 
10 

15. 6 

13 is 12 is 

20 is. 17 

. 1 18 is 

. 5 14 

18 is. 9 

15 25 

21 is 16 

16 . 9 

. 19 14 



. 5 
. 8 2 
. 1. 5 
. 5. 3 
. 3 2 
. 5. 3
*/
View Code

 

Guess you like

Origin www.cnblogs.com/mowanying/p/11514836.html