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.

        

     

     

  • 相关阅读:
    Ext架构分析(6)最简单的layout:AnchorLayout
    Ext架构分析(4)Container之旅
    ext学习资源汇总
    DomQuery v1.1 高级
    Ext 2.0 教程 目录
    HDOJ2006 ( 求奇数的乘积 ) 【水题】
    HDOJ2017 ( 字符串统计 ) 【水题】
    状态模式(State)
    HDOJ2002 ( 计算球体积 ) 【水题】
    HDOJ2007 ( 平方和与立方和 ) 【水题】
  • 原文地址:https://www.cnblogs.com/SueMiller/p/2226771.html
Copyright © 2011-2022 走看看