分析:之前的一道模拟赛题是dp+dfs,这道题是dp+bfs.

我们设f[stu][i][j]为当前状态为stu,走到(i,j)的答案,考虑怎么设计stu,每个人的状态有3种:要么在原地,要么被背着,要么已经到了终点,那么用一个3进制数保存就可以了.

下面考虑怎么转移,直接递推肯定是不对的,dfs也不行,只能bfs了.我们每次可以选择不走,或者如果当前点有人就背起来,或者到了终点就放下所有人或者放下所有使速度变慢的人,写好几次转移就过了.

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int inf = 0x7ffffff; int n, m, k, top, sx, sy, tx, ty, a[][], speed[], f[][][], dx[] = { , -, , }, dy[] = { , , , - },flag[];
char name[][],s[][]; struct node
{
int x, y, zhuangtai;
}; int jisuan(int stu)
{
int tot = ,sped = k;
memset(flag, , sizeof(flag));
while (stu)
{
tot++;
flag[tot] = stu % ;
stu /= ;
}
for (int i = ; i <= top; i++)
if (flag[i] == )
sped += speed[i];
if (sped < )
sped = ;
return sped;
} bool judge(int x, int y)
{
if (x >= && x <= n && y >= && y <= m)
return true;
return false;
} int bei(int stu, int x, int y)
{
int cur, tot = ;
for (int i = ; i <= top; i++)
if (s[x][y] == name[i][])
{
cur = i;
break;
}
memset(flag, , sizeof(flag));
while (stu)
{
tot++;
flag[tot] = stu % ;
stu /= ;
}
if (flag[cur])
return ;
flag[cur] = ;
for (int i = top; i >= ; i--)
stu = stu * + flag[i];
return stu;
} int fang1(int stu, int x, int y)
{
memset(flag, , sizeof(flag));
int tot = ;
while (stu)
{
tot++;
flag[tot] = stu % ;
stu /= ;
}
for (int i = ; i <= top; i++)
if (flag[i] == )
flag[i] = ;
for (int i = top; i >= ; i--)
stu = stu * + flag[i];
return stu;
} int fang2(int stu, int x, int y)
{
int tot = ;
memset(flag, , sizeof(flag));
while (stu)
{
tot++;
flag[tot] = stu % ;
stu /= ;
}
for (int i = ; i <= top; i++)
if (flag[i] == && speed[i] > )
flag[i] = ;
for (int i = top; i >= ; i--)
stu = stu * + flag[i];
return stu;
} int qpow(int a, int b)
{
int res = ;
while (b)
{
if (b & )
res *= a;
a *= a;
b >>= ;
}
return res;
} void bfs()
{
queue <node> q;
node temp;
temp.x = sx;
temp.y = sy;
temp.zhuangtai = ;
q.push(temp);
while (!q.empty())
{
node u = q.front();
q.pop();
int sudu = jisuan(u.zhuangtai),x = u.x,y = u.y;
//printf("%d %d %d\n", sudu, x, y);
for (int i = ; i < ; i++)
{
int nx = x + dx[i], ny = y + dy[i];
if (judge(nx, ny))
{
//只移动
if (s[nx][ny] != '#' && f[u.zhuangtai][nx][ny] > f[u.zhuangtai][x][y] + sudu)
{
f[u.zhuangtai][nx][ny] = f[u.zhuangtai][x][y] + sudu;
node temp;
temp.x = nx;
temp.y = ny;
temp.zhuangtai = u.zhuangtai;
q.push(temp);
}
//背人
if (s[nx][ny] >= 'A' && s[nx][ny] <= 'Z')
{
int stu = bei(u.zhuangtai, nx, ny);
if (f[stu][nx][ny] > f[u.zhuangtai][x][y] + sudu)
{
f[stu][nx][ny] = f[u.zhuangtai][x][y] + sudu;
node temp;
temp.zhuangtai = stu;
temp.x = nx;
temp.y = ny;
q.push(temp);
}
}
//放人
if (s[nx][ny] == 't')
{
int stu1 = fang1(u.zhuangtai, nx, ny);
int stu2 = fang2(u.zhuangtai, nx, ny);
if (f[stu1][nx][ny] > f[u.zhuangtai][x][y] + sudu)
{
f[stu1][nx][ny] = f[u.zhuangtai][x][y] + sudu;
node temp;
temp.zhuangtai = stu1;
temp.x = nx;
temp.y = ny;
q.push(temp);
}
if (f[stu2][nx][ny] > f[u.zhuangtai][x][y] + sudu)
{
f[stu2][nx][ny] = f[u.zhuangtai][x][y] + sudu;
node temp;
temp.zhuangtai = stu2;
temp.x = nx;
temp.y = ny;
q.push(temp);
}
}
}
}
}
} int main()
{
scanf("%d%d%d", &n, &m, &k);
for (int i = ; i <= n; i++)
{
scanf("%s", s[i] + );
for (int j = ; j <= m; j++)
{
if (s[i][j] == 's')
{
sx = i;
sy = j;
}
else
{
if (s[i][j] == 't')
{
tx = i;
ty = j;
}
else
{
if (s[i][j] >= 'A' && s[i][j] <= 'Z')
top++;
}
}
}
}
for (int i = ; i <= top; i++)
scanf("%s%d", name[i], &speed[i]);
for (int i = ; i <= ; i++)
for (int j = ; j <= ; j++)
for (int l = ; l <= ; l++)
f[i][j][l] = inf;
f[][sx][sy] = ;
bfs();
printf("%d\n", f[qpow(, top) - ][tx][ty]); return ;
}

最新文章

  1. SQL SERVER特殊行转列案列一则
  2. &lt;s:property value=&quot;&quot;/&gt; 怎么截取返回值的固定长度的字符串
  3. DHCP snooping
  4. PHP+ajax聊天室源码!支持长轮循跟定时请求两种
  5. Python3.4使用MySql
  6. c++内存泄漏处理(积累)
  7. OR导致笛卡尔积
  8. 修改/home内子目录的名字
  9. 一个简单用原生js实现的小游戏----FlappyBird
  10. Wince 创新布局
  11. 查看SQL Server数据读写分离,并设置读写分离
  12. oralce plsql案例练习
  13. 自定义ExtJS主题
  14. MySQL 笔记整理(8.a) --事务到底是隔离还是不隔离的?
  15. 大硬盘(大于2T)分区方法
  16. docker进阶篇(一) ---- Volume(数据卷)
  17. WEBAPI 的简单示例
  18. Py中re.sub学习【转载】
  19. linux centos6.5 php5.6 安装PHPUnit 5.2.9 (转)
  20. laravel框架5.2版本组件包开发

热门文章

  1. swoole多进程处理产生的问题
  2. JavaScript--编程练习2
  3. 解决前后端分离的“两次请求”引出的Web服务器跨域请求访问问题的解决方案
  4. EditText(8)EditText中drawableRight图片的点击事件
  5. 内联标签------------大多数XHTML可以表示为两种类型的标签:块标签(block tag)和内联标签(inline tag)
  6. Generating RSA keys in PKCS#1 format in Java--转
  7. Python(1)-第一天
  8. 重新学习Java——对象和类(二)
  9. Activity的退出和進入效果
  10. React Native组件的结构和生命周期