zoukankan      html  css  js  c++  java
  • 解题报告 Toy Bricks

    Toy Bricks

    【题目描述】

    Ray又在NPC问题了:这里有一个箱子,还有若干个玩具。 

    我们可以假设玩具的数量是没有上限的。我们还知道这个箱子是不规则的,或者可以说,他的外形比较像一个矩形,但是内部却有很多突起,这些突起很可恶,他可以一直突到玩具的顶盖部。为了简化这个NPC问题,Ray只保留了一种形状的玩具

        ○

    ○  ○  ○

        ○

    Ray想知道对于一个给定的箱子,最多可以放下多少个这样的玩具。

    【输入格式】

    第一行两个用空格隔开的整数n 和 m 表示玩具想的长度和宽度

    第二行到第n+1行,每行m个用空格隔开的字符‘#’’.‘;’#’表示这里是一个障碍物。’.’表示这里可以放东西。

    【输出格式】

    一行一个整数表示最多的玩具个数

    【输入样例】

    5 4

    #.#.

    …#

    #..#

    #...

    ##.#

    【输出样例】

    2

    【数据范围】

    0<=n<=100

    0<=m<=10

     

     

    状态压缩动规,参见炮兵阵地。

     

    program lonely;

     

      const

        maxn=maxlongint shr 1;

     

      var

        tot,jj,kk,l,zz,ttttt,ss,i,j,n,m,k,t,temp,ans:longint;

        b,sum:array[0..2000] of integer;

        z:array[0..2000] of integer;

        g:array[0..2000,0..2000] of integer;

        f:array[0..1,0..2000,0..2000] of longint;

        c:char;

     

      begin

        assign(input,'toy.in');

        reset(input);

        assign(output,'toy.out');

        rewrite(output);

     

        readln(n,m);

        fillchar(sum,sizeof(sum),0);

     

        for i:=0 to 1 shl m-1 do

          begin

            t:=i;

            while t>0 do

              begin

                inc(sum[i]);

                t:=t-(t and (-t));

              end;

          end;   //最多能放多少个

     

        fillchar(z,sizeof(z),0);

        for i:=1 to n do

          begin

            for j:=0 to m-1 do

              begin

                read(c);

                if c='#' then

                  z[i]:=z[i]+1 shl j;

              end;

            readln;

          end;   //设置障碍

     

        tot:=0;

        fillchar(g,sizeof(g),0);

        fillchar(b,sizeof(b),0);

        for i:=0 to 1 shl m-1 do

          begin

            if (i and 1=1)or(i shl 1>(1 shl m-1)) then continue;

            if (i shl 1)and i<>0 then continue;

            if (i shl 2)and i<>0 then continue;   //不能放置

            inc(tot);

            b[tot]:=i;

            g[i,0]:=0;

            for j:=0 to 1 shl m-1 do

              begin

                if (j and 1=1)or(j shl 1>(1 shl m-1)) then continue;

                if (i and j<>0) then continue;

                if (j shl 1)and j<>0 then continue;

                if (j shl 2)and j<>0 then continue;

                if (i shl 1)and j<>0 then continue;

                if (j shl 1)and i<>0 then continue;   

                inc(g[i,0]);

                g[i,g[i,0]]:=j;

              end;

          end;

     

        for i:=0 to 1 do

          for j:=0 to 1025 do

            for k:=0 to 1025 do

              f[i,j,k]:=-maxn;

        f[1,0,0]:=0;

        t:=0;

        for i:=2 to n-1 do

          begin

            for jj:=1 to tot do

              for kk:=1 to tot do

                begin

                  j:=b[jj];k:=b[kk];

                  if f[1-t,j,k]>=0 then

                    begin

                      for l:=1 to g[j,0] do

                        begin

                          temp:=g[j,l];

                          if temp and z[i]<>0 then continue;

                          if (temp shr 1)and(z[i])<>0 then continue;

                          if (temp shl 1)and(z[i])<>0 then continue;

                          if temp and z[i+1]<>0 then continue;

                          if temp and z[i-1]<>0 then continue;

                          if temp and k<>0 then continue;

                          ss:=sum[temp];

                          if f[1-t,j,k]+ss>f[t,temp,j] then

                            f[t,temp,j]:=f[1-t,j,k]+ss;

                        end;

                      f[1-t,j,k]:=-maxn;

                    end;

                end;

            t:=1-t;

          end;    //状态压缩动规。

     

        ans:=0;

        for i:=1 to tot do

          for j:=1 to tot do

            if f[1-t,b[i],b[j]]>ans then

              ans:=f[1-t,b[i],b[j]];     //统计

        writeln(ans);

     

        close(input);

        close(output);

      End.

     

     

     

     

    补充,解题报告  炮兵阵地

     

    1. 题目  炮兵阵地

        还是宇宙时间公元5.5亿年,maxingc联盟用微子来攻击yun联盟。愤怒的yun联盟决定反戈一击,他们准备使用加农炮来反击。

    yun联盟的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由NM列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队);一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 

     


    如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。 
    现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。 

    第一行包含两个由空格分割开的正整数,分别表示NM 
    接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100M <= 10

    仅一行,包含一个整数K,表示最多能摆放的炮兵部队的数量。

    Sample Input

    5 4

    PHPP

    PPHH

    PPPP

    PHPP

    PHHP

    Sample Output

    6

    2. 题目实质

    数据变态一点的,改了改要求的 皇后,不过是要求求 

    3. 题目来源  怎么又是集训?

    4. 算法

    虽然他跟 皇后怎么看怎么类似,但是从那该死的数据范围(N <= 100M <= 10)。可以看出,用单纯的搜肯定过不了。

    由于m<=10,所以每一行的状态可以用二进制表示,放置炮兵记为1,不放置记为0每一行的状态只和前两行的状态有关系,所以有方程: F[i,k1,k2]=Max{f[i-1,k2,k3]+num[k1]},其中i为行数,k1表示第i行的状态,k2表示第i-1行的状态,k3表示第i-2行的状态,num[k1]k1状态下可放置炮兵的个数。    i,k1k2k3必须满足一定的关系(炮兵之间不能相互攻击,且炮兵不能放在山地上)。    对于状态a[k1]a[k2],如果他们是可行的,讨论他们每个对应的位置。    a[k1]如果某位置是1,a[k2]这位上必须是0    a[k1]如果某位置是0,a[k2]这位上可以是1,也可以是0    所以可以归纳出  a[k1] and a[k2]=0,这要判断矛盾可以使速度大大提高。

    用这种 and 的方法可以应付很多变态的判断。    对于每一行,第i种状态能不能放上去,即要求不能在‘H’的地方放士兵。    我们可以先把每行原来的初始状态也表示出来,但是这里有个小技巧,把‘H’的地方记录下来。    这行如果某位置是1,那么在a[k1]中这个位置上必须为01代表这里是山地)。    这行如果某位置是0,那么在a[k1]中这个位置上可以为1,可以为00代表这里是平原)。    所以可以归纳出  now[i] and a[k1]=0now数组表示地形的状态)。

    当然,这种题,一般,大概,也许,都是第四题,所以拿裸宽搜偏偏分也没什么不好,不然这么变态的程序,想要在考试的时候敲出来真的是有点……

    5. 注意事项

    注意看数据范围,这玩意跟 皇后还真有点不一样。

    这里的二进制优化也就是 HASH 优化,所以注意这关键的 HASH 函数要写对!

    其实这个款搜有点动态规划的意思,但这个动态规划中的状态是要用款搜进行预处理的,千万别忘了。

    还有这个判断矛盾的方法可以学一下。

    6. 时空复杂度  On^2

    7. 程序代码

    Pascal

    var f:array[0..100,0..100,0..100] of longint;

    now,b,a:array[0..100] of longint; ch:char;

    i,j,n,m,sum,t,tt,ans,k1,k2,k3:longint; s:string;

     function deal(x:longint):string;

      var s:string; k:longint;

       begin

        k:=x; s:='';

    while k>0 do

     begin

      s:=chr(k mod 2+48)+s;

      k:=k div 2;

     end;

      exit(s);

    end;

     begin

      assign(input,'cannon.in'); reset(input);

      assign(output,'cannon.out'); rewrite(output);

      readln(n,m);

      for i:=1 to n do

       begin

        for j:=1 to m do

         begin

          read(ch);

          if ch='H' then now[i]:=now[i]+1 shl (m-j);

        end;

          readln;

       end;

          for i:=0 to (1 shl m)-1 do

           begin

             s:=deal(i);

             for j:=1 to m-length(s) do s:='0'+s;

             tt:=0; t:=0;

             for j:=1 to m do

              if s[j]='1' then

               begin

                if (s[j+1]='1') and (j+1<=m) then t:=1;

                if (s[j+2]='1') and (j+2<=m) then t:=1;

                if t=1 then break;

                inc(tt);

               end;

                if t=0 then

                 begin

                  inc(sum);

                  a[sum]:=i;

                  b[sum]:=tt;

                 end;

           end;

                 for i:=1 to sum do

                  f[1,i,1]:=b[i];

                 for i:=2 to n do

                  for k1:=1 to sum do

                   for k2:=1 to sum do

                    if (a[k1] and a[k2]=0) and

    (a[k1] and now[i]=0) and (a[k2] and now[i-1]=0) then

      for k3:=1 to sum do

               if (a[k2] and a[k3]=0) and (a[k3] and now[i-2]=0)

                       and (a[k1] and a[k3]=0) then

                if f[i,k1,k2]<f[i-1,k2,k3]+b[k1] then

                 f[i,k1,k2]:=f[i-1,k2,k3]+b[k1];

          for i:=1 to sum do

           for j:=1 to sum do

                           if (a[i] and a[j]=0) and (a[i] and now[n]=0)

                           and (a[j] and now[n-1]=0) then

            if f[n,i,j]>ans then ans:=f[n,i,j];

    writeln(ans);

    close(input);

    close(output);

     end.

        

     

     

  • 相关阅读:
    ZOJ 2588 Burning Bridges
    POJ 1966 ZOJ 2182 Cable TV Network
    HDU 5348 MZL's endless loop
    HDU 5352 MZL's City
    Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板
    ZOJ 1119 SPF
    HDU 3452 Bonsai
    HDU 1520 Anniversary party
    POJ 2239 Selecting Courses
    POJ 1144 Network
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2226771.html
Copyright © 2011-2022 走看看