zoukankan      html  css  js  c++  java
  • pku3460 Booksort

    给定一个序列,每次可取出一段任意长度的序列插到某个位置,问至少多少次操作能让序列变为1.2.3.4......n。如果步数超过4,输出“5 or more”

    可以用双向BFS,但编程复杂度较高,用迭代加深就需要动一点脑筋想强剪枝。

    题目的最终状态是1 2 3 4 5 6 7 8,则严格递增序列为1。所谓严格递增即是说1 2 3 4 5 6,这些,而2 5,2 4 6,这种只能称之为递增,

    那么1 2 5 6 3 4 7 8的严格递增序列有4个,

    而每次操作最多一次减少3个非严格递增序列,所以有这个剪枝:if  当前递增序列个数-3*(最大深度-当前深度)>=0 then exit

    加入这个剪枝不一定能AC,序列的重构一定要写的好一点,如果用n^4的操作,绝对超时。

    顺便说一下,代码里的chaneg(i,j,k)表示把当前状态中(i..j)这个序列移动到第k个元素后面。

    View Code
      1 program pku3460(input,output);
    2 type
    3 numbertype = array[0..16] of integer;
    4 var
    5 state : numbertype;
    6 n,sum : integer;
    7 depth : integer;
    8 flag : boolean;
    9 v,cases : integer;
    10 function check(a: numbertype ):integer;
    11 var
    12 sum,i : integer;
    13 begin
    14 sum:=0;
    15 for i:=1 to n-1 do
    16 if a[i+1]<>a[i]+1 then
    17 inc(sum);
    18 exit(sum+1);
    19 end; { check }
    20 procedure init;
    21 var
    22 i : integer;
    23 begin
    24 readln(n);
    25 for i:=1 to n do
    26 read(state[i]);
    27 end; { init }
    28 procedure change(x,y,z :longint );
    29 var
    30 i,now : longint;
    31 tmp : numbertype;
    32 begin
    33 fillchar(tmp,sizeof(tmp),0);
    34 for i:=1 to x-1 do
    35 tmp[i]:=state[i];
    36 now:=x-1;
    37 for i:=y+1 to z do
    38 begin
    39 inc(now);
    40 tmp[now]:=state[i];
    41 end;
    42 for i:=x to y do
    43 begin
    44 inc(now);
    45 tmp[now]:=state[i];
    46 end;
    47 for i:=z+1 to n do
    48 tmp[i]:=state[i];
    49 state:=tmp;
    50 end; { change }
    51 procedure dfs(now: integer );
    52 var
    53 i,j,k : integer;
    54 tmp : numbertype;
    55 begin
    56 if now>depth then
    57 exit;
    58 for i:=1 to n do
    59 if state[i]>state[i+1] then
    60 break;
    61 if i=n then
    62 flag:=true;
    63 sum:=check(state);
    64 if (sum-3*(depth-now+1)>=0) then
    65 exit;
    66 if flag then
    67 exit;
    68 tmp:=state;
    69 for i:=1 to n-1 do
    70 for j:=i to n-1 do
    71 for k:=j+1 to n do
    72 begin
    73 change(i,j,k);
    74 dfs(now+1);
    75 state:=tmp;
    76 if flag then
    77 exit;
    78 end;
    79 end; { dfs }
    80 procedure main;
    81 begin
    82 for depth:=0 to 4 do
    83 begin
    84 flag:=false;
    85 dfs(0);
    86 if flag then
    87 break;
    88 end;
    89 if flag then
    90 writeln(depth)
    91 else
    92 writeln('5 or more');
    93 end; { main }
    94 begin
    95 readln(cases);
    96 for v:=1 to cases do
    97 begin
    98 init;
    99 main;
    100 end;
    101 end.



  • 相关阅读:
    sql总结
    2018年6月10日笔记
    Docker入门之zabbix-agent篇
    2018年6月7日笔记
    2018年6月5日笔记
    Docker入门之container篇
    Docker入门之image篇
    Docker 入门
    2018年5月31日笔记
    2018年5月29日笔记
  • 原文地址:https://www.cnblogs.com/neverforget/p/2402945.html
Copyright © 2011-2022 走看看