不难发现两边的活动是交替进行的,我们可以dp

先对时间离散化,设f[i,j]到时间i一个会场选j个活动,另一个会场最多有多少活动,那么f[i,j]=max(f[k,j]+s[k,i],f[k,j-s[k,i]])

然后第一问的答案就是max(min(f[n*2,i],i))

第二问是要求必选一个,那这一定形如中间一段必须选,向左向右分别dp

假设中间那段是(i,j)时最优值是g[i,j]

肯定要预处理时间i前一个会场选j个活动,另一个会场最多有多少活动和时间i到结束一个会场选j个活动,另一个会场最多有多少活动

我们记为fl[i,j],fr[i,j],不难得到g[i,j]=max{min(x+y+s[i,j],fl[i,x]+fr[j,y])} (注意到f[]数组的两个会场取值是对称的)

处理g[i,j]是O(n4)的,拍几组数据可以发现当i,j固定时,随着x的增大,对应最优的y减小

其实主观上也很好理解,肯定是两个会场活动尽量平衡,证明吗……不会……

  1 var fl,fr,f,g:array[0..410,0..410] of longint;
  2     a,s,e:array[0..410] of longint;
  3     i,n,m,k,j,x,y,ans,t:longint;
  4 
  5 procedure max(var a:longint; b:longint);
  6   begin
  7     if a<b then a:=b;
  8   end;
  9 
 10 function min(a,b:longint):longint;
 11   begin
 12     if a>b then exit(b) else exit(a);
 13   end;
 14 
 15 procedure swap(var a,b:longint);
 16   var c:longint;
 17   begin
 18     c:=a;
 19     a:=b;
 20     b:=c;
 21   end;
 22 
 23 procedure sort(l,r:longint);
 24   var i,j,x:longint;
 25   begin
 26     i:=l;
 27     j:=r;
 28     x:=a[(l+r) shr 1];
 29     repeat
 30       while a[i]<x do inc(i);
 31       while x<a[j] do dec(j);
 32       if not(i>j) then
 33       begin
 34         swap(a[i],a[j]);
 35         inc(i);
 36         dec(j);
 37       end;
 38     until i>j;
 39     if l<j then sort(l,j);
 40     if i<r then sort(i,r);
 41   end;
 42 
 43 function find(l,r,x:longint):longint;
 44   var m:longint;
 45   begin
 46     while l<=r do
 47     begin
 48       m:=(l+r) shr 1;
 49       if a[m]=x then exit(m);
 50       if a[m]>x then r:=m-1 else l:=m+1;
 51     end;
 52   end;
 53 
 54 begin
 55   readln(n);
 56   for i:=1 to n do
 57   begin
 58     readln(s[i],e[i]);
 59     e[i]:=s[i]+e[i];
 60     inc(t);
 61     a[t]:=s[i];
 62     inc(t);
 63     a[t]:=e[i];
 64   end;
 65   sort(1,t);
 66   m:=1;
 67   for i:=2 to t do
 68     if a[i]<>a[m] then
 69     begin
 70       inc(m);
 71       a[m]:=a[i];
 72     end;
 73   for i:=1 to n do
 74   begin
 75     s[i]:=find(1,m,s[i]);
 76     e[i]:=find(1,m,e[i]);
 77     inc(g[s[i],e[i]]);
 78   end;
 79   for i:=1 to m do
 80     for j:=i+1 to m do
 81       inc(g[i,j],g[i,j-1]);
 82   for j:=1 to m do
 83     for i:=j-1 downto 1 do
 84       inc(g[i,j],g[i+1,j]);
 85   for i:=0 to m+1 do
 86     for j:=0 to n do
 87     begin
 88       fl[i,j]:=-n;
 89       fr[i,j]:=-n;
 90     end;
 91   fl[0,0]:=0; fr[m+1,0]:=0;
 92   for i:=1 to m do
 93     for j:=0 to i-1 do
 94       for k:=0 to n do
 95       begin
 96         max(fl[i,k],fl[j,k]+g[j,i]);
 97         if k>=g[j,i] then max(fl[i,k],fl[j,k-g[j,i]]);
 98       end;
 99   for i:=m downto 1 do
100     for j:=i+1 to m+1 do
101       for k:=0 to n do
102       begin
103         max(fr[i,k],fr[j,k]+g[i,j]);
104         if k>=g[i,j] then max(fr[i,k],fr[j,k-g[i,j]]);
105       end;
106   ans:=0;
107   for i:=0 to n do
108     max(ans,min(fl[m,i],i));
109   writeln(ans);
110   for i:=1 to m do
111     for j:=i to m do
112     begin
113       y:=g[j,m];
114       for x:=0 to g[1,i] do
115       begin
116         while (y>0) and (min(x+y-1+g[i,j],fl[i,x]+fr[j,y-1])>=min(x+y+g[i,j],fl[i,x]+fr[j,y])) do dec(y);
117         max(f[i,j],min(x+y+g[i,j],fl[i,x]+fr[j,y]));
118       end;
119     end;
120 
121   for i:=1 to n do
122   begin
123     ans:=0;
124     for x:=1 to s[i] do
125       for y:=e[i] to m do
126         max(ans,f[x,y]);
127     writeln(ans);
128   end;
129 end.
View Code

 

 

 

posted on 2015-06-30 15:50  acphile  阅读(300)  评论(0编辑  收藏  举报