分析:之前的一道模拟赛题是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 ;
}

noip模拟赛 蒜头君救人的更多相关文章

  1. noip模拟赛 蒜头君的兔子

    分析:直接暴力算有30分,像斐波那契那样推式子算有60分,如果想要得到100分就要用一种数列题的常见优化--矩阵了. 当前的兔子数和十年内的兔子数有关,我们需要1个1*11的矩阵,来记录当前为0岁.1 ...

  2. noip模拟赛 蒜头君的排序

    分析:其实就是求m个区间的逆序对个数,题目真的是明摆着让我们用莫队算法,套用树状数组就可以了. 具体怎么转移呢?如果移动R,那么对区间[l,r]有影响的是R左边的元素,我们只需要看有多少在R左边比a[ ...

  3. noip模拟赛 蒜头君的坐骑

    分析:标准的棋盘dp问题. 如果没有技能,那么就很好做了,相当于传纸条的做法.有了技能的限制,我们就要加上一维表示用了多少次技能,这个时候转移就要用到dfs了,而且不能用填表法,要用刷表法,从当前位置 ...

  4. noip模拟赛 蒜头君的树

    分析:这道题问的是树上整体的答案,当然要从整体上去考虑. 一条边对答案的贡献是这条边一端连接的点的个数*另一端连接的点的个数*边权,可以用一次dfs来统计答案,之后每次更改操作在原答案的基础上增减就好 ...

  5. noip模拟赛 蒜头君打地鼠

    分析:直接一个一个地去暴力枚举分数比较少,我们需要一种比较快的统计一定空间内1的数量,标准做法是前缀和,但是二维前缀和维护的是一个矩形内的值,这个是旋转过的该怎么办?可以把图旋转45°,不过这样比较考 ...

  6. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  7. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  8. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  9. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

随机推荐

  1. bzoj 1642: [Usaco2007 Nov]Milking Time 挤奶时间【dp】

    这不就是个n方dp吗--看了眼洛谷题解简直神仙打架 我全程没用到n-- 把休息时间并入产奶时间,注意"结束时间不挤奶",所以ei=ei+r-1,注意这个-1! 然后按r排序,设f[ ...

  2. 【懒人专用系列】Xind2TestCase的初步探坑

    公司最近说要弄Xind2TestCase,让我们组先试用一下 解释:https://testerhome.com/topics/17554 github项目:https://github.com/zh ...

  3. moiezen

    这题是个随机化+二分裸题--------考场上居然没有想出来--想的出来就怪了吧 我们随机一下增加x的顺序,然后进行二分之前,看看这个x加完之后能不能更新答案,不能就不二分了.具题解所说,这个复杂度是 ...

  4. 洛谷P1010 幂次方

    题目描述 任何一个正整数都可以用2的幂次方表示.例如 137=2^7+2^3+2^0 同时约定方次用括号来表示,即a^b 可表示为a(b). 由此可知,137137可表示为: 2(7)+2(3)+2( ...

  5. MVC、MVP和MVVM的图示

    一.MVC MVC模式的意思是,软件可以分成三个部分. 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 各部分之间的通信方式如下. View 传送 ...

  6. P2P 网络核心技术:Gossip 协议

    背景 Gossip protocol 也叫 Epidemic Protocol (流行病协议),实际上它还有很多别名,比如:“流言算法”.“疫情传播算法”等. 这个协议的作用就像其名字表示的意思一样, ...

  7. Redis作者:深度剖析Redis持久化

    Redis是一种面向“key-value”类型数据的分布式NoSQL数据库系统,具有高性能.持久存储.适应高并发应用场景等优势.它虽然起步较晚,但发展却十分迅速. 近日,Redis的作者在博客中写到, ...

  8. 为什么字符串类型可以调用构造函数String的方法,却又不是它的实例

    从所周知,在js中定义一个字符串我们有两种办法: var a = new String("a"); var a = "a"; 第一种方法使用构造函数创建,作为S ...

  9. postgreSQL在Centos6下编译安装

    1.准备安装源 下载地址:https://www.postgresql.org/ftp/source/ 下载并解压. 2.软件编译安装 配置.检查安装环境 ./configure --prefix=/ ...

  10. 2星|《约见投资人》:A股上市公司软文集

    约见资本人:58家上市公司创始人亲述创业之路 全书写了58个A股上市公司的故事,基本是宣传上市公司老总的软文.基本的套路是创始人历尽苦难创立了公司,取得了好业绩.最希望看的分析与数据几乎没有.看了一小 ...