分析:之前的一道模拟赛题是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. 17年day3

    /* 嗯,又一天. 时日无多了,还能蹦哒几天? 上午依旧考试,日常挂T1,读错题.还是好困. 兔子说明天晚上要请我们吃水饺~~~~去年就没这待遇. 下午打开邮箱一看,咦?嗯. 昨晚做噩梦NOIP考了状 ...

  2. 开车旅行 2012年NOIP全国联赛提高组(倍增+set)

    开车旅行 2012年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 小A 和小B决定利用 ...

  3. 例题 5-1 STL

    Raju and Meena love to play with Marbles. They have got a lot of marbles with numbers written on the ...

  4. 有关lower_bound()函数的使用

    lower_bound()函数需要加载头文件#include<algorithm>,其基本用途是查找有序区间中第一个大于或等于某给定值的元素的位置,其中排序规则可以通过二元关系来表示. 函 ...

  5. BFS(最短路) HDU 2612 Find a way

    题目传送门 /* BFS:和UVA_11624差不多,本题就是分别求两个点到KFC的最短路,然后相加求最小值 */ /***************************************** ...

  6. yii框架下jquery在ajax更新后失效问题

    解决方案,以live的形式重新绑定一次, /***回复隐藏收起效果***/ $(".btn-reply").live('click',function(event){ var da ...

  7. C# 自动批量导入图片到数据库中

    using Model; using System; using System.Collections.Generic; using System.Data; using System.Data.Sq ...

  8. hbase优化小结

    目录: 1,背景 2,GC 3,hbase cache 4,compaction 5,其他 1,背景 项目组中,hbase主要用来备份mysql数据库中的表.主要通过接入mysql binlog,经s ...

  9. LN : leetcode 515 Find Largest Value in Each Tree Row

    lc 515 Find Largest Value in Each Tree Row 515 Find Largest Value in Each Tree Row You need to find ...

  10. 树莓派zero_w设置中文(已成功)

    树莓派默认是采用英文字库的,而且系统里没有预装中文字库,所以即使你在locale中改成中文,也不会显示中文,只会显示一堆方块.因此需要我们手动来安装中文字体. 好在有一个中文字体是免费开源使用的.ss ...