NOIP 2011 提高组 选择客栈(vijos 1737)(方法:队列,数学)


        附:   题目链接                vijos 1737                                        地址:https://www.vijos.org/p/1737


                                          srO     来自嘘嘘大神@oxxxo 的神级O(n) 打法     Orz

                                          srO     而且该打法不长,可丧心病狂的压到10行     Orz


      该题嘘嘘大神@oxxxo 的思路:

            对于每个客栈(最低消费 v,格调 c),在、之前的、出现的所有、跟、该客栈、同格调的客栈、符合旅客要求、的前提是 :

            在、这两客栈间存在一家最低消费<= p 的客栈,记 f 为离当前决策客栈、最近的、最低消费 <= p的、客栈编号,则、当前

      决策点之前、能与该点、组成符合要求的、客栈即为:前 f 家客栈中、与该决策客栈同格调的客栈。

            所以思路就很明显了:开一个 can[0..50] 的数组记录前 f 家客栈中格调为 x的数量,记为 can[x]  ;则、当前决策点能增加

      的方案数为 can[x] ,每次只要把 answer 的值加上 can[决策点]的值即可。

            按这个思路,最后要完成的步骤就是: 对 can 这个数组的维护,按嘘嘘大神的方法,再开一个 tot[0..50] 数组、来记录:当

      前决策点前、格调为 x的客栈数量,记为 tot[x] ; 以及用last[0..50] 来记录:上一个、格调为 x的客栈编号,记为 last[x]。

            那么、每次决策时,只要先更新 f的值(即、如果该决策点、符合最低消费要求,则将、最近消费点f、更新为当前决策点);再判

      断如果、 f 的值>= last[当前决策点格调] ,即上一个、和决策点 同格调的客栈编号,那么说明:离该点最近的、同格调的客栈、与

      决策点之间、有符合最低消费的、客栈。那么就可以将 can[ x]的值更新为 tot[x] (x为当前决策点格调),因为出现的x格调都可记入

      方案数。

           然后看代码~~~~~


      var

      last,tot,can:array[0..51] of longint;                                   //3个数组上面都有提到
      n,k,p,i,answer,flag,color,cost:longint;                                //answer记录总方案数,flag为当前决策之前最近的消费点

      begin
        readln(n,k,p);
        for i := 1 to n do begin
          readln(color,cost);                                                      //采用边读边做,因为所有有用信息均有记录
          if cost <= p then flag := i;                                           //更新最近消费点
          if flag >= last[color] then can[color]:=tot[color];            //更新 can 数组的值
          inc(answer,can[color]);                                                //记录前 i 点、与第 i 点、构成的、符合要求的方案数
          inc(tot[color]);                                                            //更新tot 数组的值
          last[color]:=i;                                                              //更新last 数组的值
      end;

      writeln(answer);

      end.


       Ps:因为对于每个客栈,f 更新一次,并将该客栈格调相关数组值更新,所以是相当科学的~~~~~~~~~~~~~~~~~


                                                    srO     附:  嘘嘘大神原题解链接     Orz

                                        srO http://www.cnblogs.com/oxxxo/p/3370853.html Orz


 

posted @ 2013-10-17 14:58  哥少先队的  阅读(508)  评论(0编辑  收藏  举报