zoukankan      html  css  js  c++  java
  • 2436: [Noi2011]Noi嘉年华

    Description

    NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,
    吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办。每
    个嘉年华可能包含很多个活动,而每个活动只能在一个嘉年华中举办。
    现在嘉年华活动的组织者小安一共收到了 n个活动的举办申请,其中第 i 个
    活动的起始时间为 Si,活动的持续时间为Ti。这些活动都可以安排到任意一个嘉
    年华的会场,也可以不安排。
    小安通过广泛的调查发现,如果某个时刻,两个嘉年华会场同时有活动在进
    行(不包括活动的开始瞬间和结束瞬间),那么有的选手就会纠结于到底去哪个
    会场,从而变得不开心。所以,为了避免这样不开心的事情发生,小安要求不能
    有两个活动在两个会场同时进行(同一会场内的活动可以任意进行)。
    另外,可以想象,如果某一个嘉年华会场的活动太少,那么这个嘉年华的吸
    引力就会不足,容易导致场面冷清。所以小安希望通过合理的安排,使得活动相
    对较少的嘉年华的活动数量最大。
    此外,有一些活动非常有意义,小安希望能举办,他希望知道,如果第i 个
    活动必须举办(可以安排在两场嘉年华中的任何一个),活动相对较少的嘉年华
    的活动数量的最大值。
    Input

     

    输入的第一行包含一个整数 n,表示申请的活动个数。
    接下来 n 行描述所有活动,其中第 i 行包含两个整数 Si、Ti,表示第 i 个活
    动从时刻Si开始,持续 Ti的时间。
    Output


    输出的第一行包含一个整数,表示在没有任何限制的情况下,活动较少的嘉
    年华的活动数的最大值。
    接下来 n 行每行一个整数,其中第 i 行的整数表示在必须选择第 i 个活动的
    前提下,活动较少的嘉年华的活动数的最大值。

     
    Sample Input

    5
    8 2
    1 5
    5 3
    3 2
    5 3
    Sample Output
    2
    2
    1
    2
    2
    2
    HINT


    在没有任何限制的情况下,最优安排可以在一个嘉年华安排活动 1, 4,而在

    另一个嘉年华安排活动 3, 5,活动2不安排。

    1≤n≤200 0≤Si≤10^9

     

    1≤Ti≤ 10^9

    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)}

    第二问是要求必选一个,那么我们想像这一个一定在方案中的某一段中

    假设区间是(i,j),那么最优值是g[i,j],我们预处理出所有的g[i,j]就可以n^3回答所有的询问了

    然后我们现在要考虑的是怎么算g[i,j]

    因为去掉(i,j)变成左边和右边两部分,所以开始我们dp两次,一个从左边开始一个从右边开始,就可以算g[i,j]了

    g[i,j]=max{min(x+y+s[i,j],l[i,x]+r[j,y])}

    但是直接枚举是不行的(艹,还让不让人愉快的做题了......)

    但是其实x固定,关于y是单峰函数,而且x增大的话,最优值y会减小(因为要尽量平衡),然后就可以x for一遍,y一直递减就行了

    所以n^3可以预处理出g[i,j],然后就做完了(wikioi过不去,又用优化代码过去了233,在我之前没有pascal在wikioi过的)

     1 const
     2     maxn=420;
     3 var
     4     a,b:array[0..maxn,0..1]of longint;
     5     s,l,r,f:array[0..maxn,0..maxn]of longint;
     6     n,k,cnt:longint;
     7 
     8 procedure up(var x:longint;y:longint);
     9 begin
    10     if x<y then x:=y;
    11 end;
    12 
    13 function min(x,y:longint):longint;
    14 begin
    15     if x<y then exit(x);
    16     exit(y);
    17 end;
    18 
    19 procedure main;
    20 var
    21     i,j,g,x,y,minx,ans:longint;
    22 begin
    23     read(n);
    24     for i:=1 to n do
    25         begin
    26             read(a[i,0],a[i,1]);
    27             inc(a[i,1],a[i,0]);
    28         end;
    29     while cnt<n<<1 do
    30         begin
    31             minx:=maxlongint;inc(k);
    32             for i:=1 to n do
    33                 for j:=0 to 1 do
    34                     if (b[i,j]=0) and (a[i,j]<minx) then minx:=a[i,j];
    35             for i:=1 to n do
    36                 for j:=0 to 1 do
    37                     if (a[i,j]=minx) and (b[i,j]=0) then
    38                     begin
    39                         inc(cnt);b[i,j]:=1;
    40                         a[i,j]:=k;
    41                     end;
    42         end;
    43     for i:=1 to n do inc(s[a[i,0],a[i,1]]);
    44     for i:=1 to k do
    45         for j:=i+1 to k do
    46             inc(s[i,j],s[i,j-1]);
    47     for  j:=2 to k do
    48         for i:=j downto 2 do
    49             inc(s[i-1,j],s[i,j]);
    50     fillchar(l,sizeof(l),200);
    51     fillchar(r,sizeof(r),200);
    52     l[0,0]:=0;r[k+1,0]:=0;
    53     for i:=1 to k do
    54         for j:=0 to n do
    55             for g:=0 to i-1 do
    56                 begin
    57                     up(l[i,j],l[g,j]+s[g,i]);
    58                     if j>=s[g,i] then up(l[i,j],l[g,j-s[g,i]]);
    59                 end;
    60     for i:=k downto 1 do
    61         for j:=0 to n do
    62             for g:=i+1 to k+1 do
    63                 begin
    64                     up(r[i,j],r[g,j]+s[i,g]);
    65                     if j>=s[i,g] then up(r[i,j],r[g,j-s[i,g]]);
    66                 end;
    67     ans:=0;
    68     for i:=0 to n do
    69         up(ans,min(l[k,i],i));
    70     writeln(ans);
    71     for i:=1 to k do
    72         for j:=i to k do
    73             begin
    74                 y:=s[j,k];
    75                 for x:=0 to s[1,i] do
    76                     begin
    77                         while (y>0) and (min(x+y-1+s[i,j],l[i,x]+r[j,y-1])>=min(x+y+s[i,j],l[i,x]+r[j,y])) do dec(y);
    78                         up(f[i,j],min(x+y+s[i,j],l[i,x]+r[j,y]));
    79                     end;
    80             end;
    81     for i:=1 to n do
    82         begin
    83             ans:=0;
    84             for x:=1 to a[i,0] do
    85                 for y:=a[i,1] to k do
    86                     up(ans,f[x,y]);
    87             writeln(ans);
    88         end;
    89 end;
    90 
    91 begin
    92     main;
    93 end.
    View Code
  • 相关阅读:
    2017博普杯 东北大学邀请赛(B. Drink too much water)(贪心+树链剖分)
    AGC018D Tree and Hamilton Path(树+树的重心)
    BZOJ2843:极地旅行社
    P++ 1.0.5
    BZOJ1052:[HAOI2007]覆盖问题
    BZOJ3098:Hash Killer II
    BZOJ2784:[JLOI2012]时间流逝
    BZOJ2282:[SDOI2011]消防
    BZOJ1875:[SDOI2009]HH去散步
    Codeforces 504 A (Round #285 div.1 A) Misha and Forest
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3800163.html
Copyright © 2011-2022 走看看