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 */