zoukankan      html  css  js  c++  java
  • 蒜头君救人

    蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境,假设蒜头君所在的村子是 n imes mn×m 的网格,网格中.号代表平地,#号代表该地已被洪水淹没,AB……等大写字母表示该地有村民被困,s代表蒜头君的起点,t代表蒜头君的终点。

    蒜头君的初始速度为 kk 秒一格,他每次可以向上下左右 44 个方向中的一个移动 11 格。在背上一个村民后,他的速度可能会降低,也可能会加快,但他的速度不能快于 11 秒每格,那么蒜头君想知道,他最快需要多长时间将所有村民救出?

    注意:不能在终点以外的地方放下村民;可以同时背多个村民。

    输入格式

    第一行 33 个正整数 n,m,kn,m,k,分别表示村庄长度、宽度、蒜头君初始速度。

    接下来 nn 行,每行一个长度为 mm 的字符串,表示村庄的地形,字符串意义如上所述。

    接下来若干行,每行一个大写字母、一个整数,表示该编号的村民会使 kk 增加 / 减少多少。行数等同于地形中大写字母的个数。大写字母按字典序,即ABC的顺序排列,保证前后两行的字母是连续的。

    输出格式

    输出 11 个整数,表示最小用时。

    数据规模

    对于 10% 的数据,满足 1 le n,m le 51n,m5,村民个数为 11;

    对于 50% 的数据,满足 1le n,mle51n,m5,村民个数小于等于 55;

    对于 100% 的数据,满足 1le n,mle101n,m10,村民个数小于等于 1010。

    样例输入

    4 4 2
    s.##
    ..A#
    .B##
    ...t
    A -3
    B 4

    样例输出

    17
    题解:dp
    首先是50分做法:
    定义f[2^num][2^num][x][y]
    第一维每一位若为 1 表示该村民正被蒜头君所背,第二维每一位若为1表示该村民已被放至安全地带,
    最后两维表示蒜头君当前所处位置。
    转移时分别考虑是否有村民,是否是终点就行了
    复杂度为O(4^num*n*m)
    100分:
    将一维和二维合起来,定义一个三进制数,0表示还没救,1表示背在身上,2表示已送达
    转移用记忆化搜索就行了,不用考虑转移顺序,但YZD大神直接dp,效率贼高
    在到终点时,不用枚举子集,直接考虑2种情况:
    1.把会减慢速度的人放下
    2.把所有人放下
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 using namespace std;
      6 struct Node
      7 {
      8     int x,y,s;
      9 }q[2000001];
     10 int dx[5]={0,1,-1,0,0},dy[5]={0,0,0,1,-1};
     11 int peo[11],k,n,m,t,sp[11],pw[11];
     12 int f[60001][11][11];
     13 char a[11][11],s[11][11];
     14 int cal_spd(int x)
     15 {int p=0,ss=0,i;
     16 memset(peo,0,sizeof(peo));
     17     while (x)
     18     {
     19         p++;
     20         peo[p]=x%3;
     21         x/=3;
     22     }
     23     ss=k;
     24     for (i=1;i<=t;i++)
     25     {
     26         if (peo[i]==1) 
     27         {
     28             ss+=sp[i];
     29         }
     30     }
     31     if (ss<1) ss=1;
     32     return ss;
     33 }
     34 int pick(int ss,int x,int y)
     35 {int i,po,p=0;
     36     for (i=1;i<=t;i++)
     37     if (a[x][y]==s[i][0]) 
     38     {
     39       po=i;break;
     40     }
     41     memset(peo,0,sizeof(peo));
     42     while (ss)
     43     {
     44         p++;
     45         peo[p]=ss%3;
     46         ss/=3;
     47     }
     48     for (i=1;i<=t;i++)
     49     if (peo[po]) return 0;
     50     peo[po]=1;
     51     for (i=t;i>=1;i--)
     52     ss=ss*3+peo[i];
     53     return ss;
     54 }
     55 int drop1(int ss,int x,int y)
     56 {int p=0,i;
     57     memset(peo,0,sizeof(peo));
     58     while (ss)
     59     {
     60         p++;
     61         peo[p]=ss%3;
     62         ss/=3;
     63     }
     64     for (i=1;i<=t;i++)
     65     if (peo[i]==1) peo[i]=2;
     66     for (i=t;i>=1;i--)
     67     ss=ss*3+peo[i];
     68     return ss;
     69 }
     70 int drop2(int ss,int x,int y)
     71 {int p=0,i;
     72     memset(peo,0,sizeof(peo));
     73     while (ss)
     74     {
     75         p++;
     76         peo[p]=ss%3;
     77         ss/=3;
     78     }
     79     for (i=1;i<=t;i++)
     80     if (peo[i]==1&&sp[i]>0) peo[i]=2;
     81     for (i=t;i>=1;i--)
     82     ss=ss*3+peo[i];
     83     return ss;
     84 }
     85 int main()
     86 {int i,j,xh,yh,xt,yt,head,tail;
     87     scanf("%d%d%d",&n,&m,&k);
     88     for (i=1;i<=n;i++)
     89     {
     90         scanf("%s",a[i]+1);
     91         for (j=1;j<=m;j++)
     92         if (a[i][j]=='s') xh=i,yh=j;
     93         else if (a[i][j]=='t') xt=i,yt=j;
     94         else 
     95         if (a[i][j]>='A'&&a[i][j]<='Z') t++;
     96     }
     97      for (i=1;i<=t;i++)
     98      {
     99          scanf("%s%d",s[i],&sp[i]);
    100      }
    101      pw[0]=1;
    102      for (i=1;i<=t;i++)
    103      pw[i]=pw[i-1]*3;
    104      memset(f,127/3,sizeof(f));
    105      f[0][xh][yh]=0;
    106       q[1].x=xh;q[1].y=yh;q[1].s=0;
    107       head=0;tail=1;
    108       while (head<tail)
    109       {
    110            head++;
    111            head%=2000000;
    112              int spd=cal_spd(q[head].s);
    113                int nx=q[head].x,ny=q[head].y;
    114                for (i=1;i<=4;i++)
    115                {
    116                    int x=nx+dx[i],y=ny+dy[i];
    117                    if (x>=1&&x<=n&&y>=1&&y<=m)
    118                    {
    119                        if (a[x][y]!='#'&&f[q[head].s][x][y]>f[q[head].s][nx][ny]+spd)
    120                        {
    121                            f[q[head].s][x][y]=f[q[head].s][nx][ny]+spd;
    122                            tail++;tail%=2000000;
    123                            q[tail].s=q[head].s;q[tail].x=x;q[tail].y=y;
    124                     }
    125                     if (a[x][y]>='A'&&a[x][y]<='Z')
    126                     {
    127                         int nxt=pick(q[head].s,x,y);
    128                          if (f[nxt][x][y]>f[q[head].s][nx][ny]+spd)
    129                          {
    130                              f[nxt][x][y]=f[q[head].s][nx][ny]+spd;
    131                              tail++;tail%=2000000;
    132                              q[tail].s=nxt;q[tail].x=x;q[tail].y=y;
    133                          }
    134                     }
    135                     if (a[x][y]=='t')
    136                     {
    137                         int nxt1=drop1(q[head].s,x,y);
    138                         int nxt2=drop2(q[head].s,x,y);
    139                         if (f[nxt1][x][y]>f[q[head].s][x][y])
    140                         {
    141                             f[nxt1][x][y]=f[q[head].s][x][y];
    142                             tail++;tail%=2000000;
    143                             q[tail].s=nxt1;q[tail].x=x;q[tail].y=y;
    144                         }
    145                         if (f[nxt2][x][y]>f[q[head].s][x][y])
    146                         {
    147                             f[nxt2][x][y]=f[q[head].s][x][y];
    148                             tail++;tail%=2000000;
    149                             q[tail].s=nxt2;q[tail].x=x;q[tail].y=y;
    150                         }
    151                     }
    152                 }
    153              }    
    154       }
    155     cout<<f[pw[t]-1][xt][yt];
    156 }
  • 相关阅读:
    canvas 方法参数智能提示
    layui 关闭弹窗,刷新父窗体页面
    UI设计灵感集结地
    Java Poi 读取excel 对所有类型进行处理
    jeecg v3.6.6 excel导入js方法完善
    父、子页面之间页面元素的获取,方法的调用
    ps载入渐变
    ps载入画笔
    做设计常用的素材下载网站
    色彩搭配神器
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7260427.html
Copyright © 2011-2022 走看看