zoukankan      html  css  js  c++  java
  • 【SDOI 2009】学校食堂 Dining

      http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1226

    [SDOI2009]学校食堂Dining

    Time Limit:10000MS  Memory Limit:265536K
    Total Submit:62 Accepted:34
    Case Time Limit:1000MS

    Description

      小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭。学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴。当然,不同的人口味也不一定相同,但每个人的口味都可以用一个非负整  数表示。
      由于人手不够,食堂每次只能为一个人做菜。做每道菜所需的时间是和前一道菜有关的,若前一道菜的对应的口味是a,这一道为b,则做这道菜所需的时间为(a or b)-(a and b),而做第一道菜是不需要计算时间的。其中,or 和and 表示整数逐位或运算及逐位与运算,C语言中对应的运算符为“|”和“&”。
    学生数目相对于这个学校还是比较多的,吃饭做菜往往就会花去不少时间。因此,学校食堂偶尔会不按照大家的排队顺序做菜,以缩短总的进餐时间。
      虽然同学们能够理解学校食堂的这种做法,不过每个同学还是有一定容忍度的。也就是说,队伍中的第i 个同学,最多允许紧跟他身后的Bi 个人先拿到饭菜。一旦在此之后的任意同学比当前同学先拿到饭,当前同学将会十分愤怒。因此,食堂做菜还得照顾到同学们的情绪。
    现在,小F 想知道在满足所有人的容忍度这一前提下,自己的学校食堂做完这些菜最少需要多少时间。

    Input

      第一行包含一个正整数C,表示测试点的数据组数。
      每组数据的第一行包含一个正整数N,表示同学数。
      每组数据的第二行起共N行,每行包含两个用空格分隔的非负整数Ti和Bi,表示按队伍顺序从前往后的每  个同学所需的菜的口味和这个同学的忍受度。
      每组数据之间没有多余空行。

    Output

      包含C行,每行一个整数,表示对应数据中食堂完成所有菜所需的最少时间。

    Sample Input

    2
    5
    5 2
    4 1
    12 0
    3 3
    2 2
    2
    5 0
    4 0

    Sample Output

    16
    1

    Hint

      对于第一组数据:
      同学1允许同学2或同学3在他之前拿到菜;同学2允许同学3在他之前拿到菜;同学3比较小气,他必须比他后面的同学先拿菜……
      一种最优的方案是按同学3、同学2、同学1、同学4、同学5做菜,每道菜所需的时间是0、8、1、6及1。
    【数据规模和约定】
    对于30%的数据,满足1 ≤ N ≤ 20。
    对于100%的数据,满足1 ≤ N ≤ 1,000,0 ≤ Ti ≤ 1,000,0 ≤ Bi ≤ 7,1 ≤ C ≤ 5。
    存在30%的数据,满足0 ≤ Bi ≤ 1。
    存在65%的数据,满足0 ≤ Bi ≤ 5。
    存在45%的数据,满足0 ≤ Ti ≤ 130。

      最近真的被状态压缩虐爆了……>_<

      看到Bi<=7,就会往状压dp上想……这个题对我来说相当难……看了解题报告,写完又改了半天才AC掉……

      写的可能有问题……谅解……

      首先明确一点:(a or b)-(a and b)=a xor b。为啥?自己想想、、、

      我们知道,第i个人排队时,他可以容忍最多七个他后面的人先于他拿到菜,那么我们可以这样表示:

      f[i,j,k]表示第i个人之前的人全都拿到菜,他后面还没有取菜的人的集合j{...},前一个取菜的人是k的最小时间。而对于k的表示我们不必使用1..n来表示,只记录一个相对于i的位置坐标就可以了。比如,k=1,即k是i后面第一个人,k=-2表示i前面第2个人。这样,k的状态就可以用[-8..7]来表示。

      然后枚举状态。当某个状态f[i,j,k]中,i后面的一个人已经取到菜,那么状态f[i,j,k]就可以传递到f[i+1,(j>>1)or(1<<7),k-1],否则,我们需要枚举一个合法的L计算最优值。

     

    program SDOI_2009_Dining;
    var f:array[0..1001,0..(1 shl 8)-1,-8..7]of longint;
        t,b:array[1..1000]of longint;
        inf,ans,Max_Anger,n,c,i,j,k,l:longint;
    
    function min(a,b:longint):longint;
    begin
      if a<b then exit(a);
      exit(b);
    end;
    
    begin
      readln(c);
      while c>0 do
        begin
          dec(c);
          readln(n);
          fillchar(t,sizeof(t),0);
          fillchar(b,sizeof(b),0);
          fillchar(f,sizeof(f),$7f);
          inf:=f[0,0,0];
          for i:=1 to n do readln(t[i],b[i]);
          f[1,1<<8-1,-1]:=0;
          for i:=1 to n do
            for j:=(1<<8)-1 downto 0 do
              for k:=-8 to 7 do
                if f[i,j,k]<inf then
                  begin
                    if (j and 1=0)then
                      f[i+1,(j>>1)or(1<<7),k-1]:=f[i,j,k]
                    else
                      begin
                        Max_Anger:=inf;
                        for l:=0 to 7 do
                          if j and (1<<l)<>0 then
                            begin
                              if i+l>Max_Anger then break;
                              Max_Anger:=min(Max_Anger,i+l+b[i+l]);
                              if i+k<=0 then f[i,j and not(1<<l),l]:=min(f[i,j and not(1<<l),l],0)
                                else f[i,j and not(1<<l),l]:=min(f[i,j and not(1<<l),l],f[i,j,k]+(t[i+k] xor t[i+l]));
                            end;
                      end;
                  end;
          ans:=maxlongint;
          for i:=-8 to -1 do
            ans:=min(ans,f[n+1,(1<<8)-1,i]);
          writeln(ans);
        end;
      readln;readln;
    end.
    
    
    
  • 相关阅读:
    Binary Tree Maximum Path Sum
    ZigZag Conversion
    Longest Common Prefix
    Reverse Linked List II
    Populating Next Right Pointers in Each Node
    Populating Next Right Pointers in Each Node II
    Rotate List
    Path Sum II
    [Leetcode]-- Gray Code
    Subsets II
  • 原文地址:https://www.cnblogs.com/Delostik/p/1987645.html
Copyright © 2011-2022 走看看