RQNOJ 342 最不听话的机器人:网格dp
题目链接:https://www.rqnoj.cn/problem/342
题意:
DD 有一个不太听话的机器人,这个机器人总是会有自己的想法,而不会完全遵守 DD 给它的指令。
现在 DD 在试图命令机器人走迷宫。迷宫是一个 N*N 个格子组成的区域,格子自左上角到右下角从 (1,1) 到 (N,N) 编号。第 i 行、第 j 列的格子编号为 (i,j)。迷宫中的某些区域是障碍物,机器人不能移动到那里。
DD 给了机器人 M 条指令,指令的类型包括“前进一步”“后退一步”“左转九十度”“右转九十度”。但问题是机器人并不能完全遵守这些指令,因为如果机器人完全遵守这些指令,它可能会走到障碍物的格子里或者走到迷宫外面去,那样就会有危险。机器人希望从这个指令序列里面去掉一些,然后执行剩下的指令时,可以保证整个过程中都不会有危险。
机器人虽然不太听话,但它并不想惹恼了 DD,否则 DD 可能会把它拆掉的。所以机器人希望去掉的指令尽量少。
迷宫的大小是 N*N,指令共有 M 条,机器人初始时的位置是 (X0,Y0)。机器人初始时面朝的方向是上方。
那么,机器人最少需要去掉多少条指令才能保证不会有危险呢?
题解:
表示状态:
dp[i][x][y][d] = min num of deleted orders
i:考虑到第i条指令
x,y:当前位置
d:当前方向
找出答案:
min legal dp[m][x][y][d]
如何转移:
now: dp[i][x][y][d]
dp[i+1][x][y][d] = min dp[i][x][y][d] + 1 (不执行)
dp[i+1][nx][ny][nd] = min dp[i][x][y][d] (执行)
nx,ny,nd为执行第i条指令后的位置和方向。
边界条件:
dp[0][x0][y0][UP] = 0
ohters = INF
(UP为方向向上的编号)
注:空间限制,要把第一维[MAX_M]变为[2]。
小技巧:
如果压维的时候前后数据间有影响,则可以开一个vis数组。
更新dp[i&1][x][y][d]时,将vis[i&1][x][y][d] = i,意为当前dp的位置是在i的时候更新的。
每次用到dp[i&1][x][y][d]时,判断一下相应的vis。
如果vis[i&1][x][y][d] = i,则返回dp值,否则返回初始值INF(dp[i][x][y][d]这个状态还没被更新过)。
AC Code:
// state expression:
// dp[i][x][y][d] = min num of deleted orders
// i: considering ith order
// x,y: present pos
// d: present direction
//
// find the answer:
// min legal dp[m][x][y][d]
//
// transferring:
// now: dp[i][x][y][d]
// dp[i+1][x][y][d] = min dp[i][x][y][d] + 1
// dp[i+1][nx][ny][nd] = min dp[i][x][y][d]
//
// bound:
// dp[0][x0][y0][UP] = 0
// ohters = INF
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 105
#define MAX_M 1005
#define MAX_D 5
#define INF 10000000 using namespace std; const int dx[]={-,,,};
const int dy[]={,,,-}; int n,m,x0,y0;
int ans;
int c[MAX_M];
int dp[][MAX_N][MAX_N][MAX_D];
int vis[][MAX_N][MAX_N][MAX_M];
char a[MAX_N][MAX_N]; void read()
{
cin>>n>>m>>x0>>y0;
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
cin>>a[i][j];
}
}
string s;
for(int i=;i<m;i++)
{
cin>>s;
if(s=="FORWARD") c[i]=;
if(s=="BACK") c[i]=;
if(s=="LEFT") c[i]=;
if(s=="RIGHT") c[i]=;
}
} void cal_pos(int &x,int &y,int &d,int c)
{
if(c==)
{
x+=dx[d];
y+=dy[d];
return;
}
if(c==)
{
x-=dx[d];
y-=dy[d];
return;
}
if(c==)
{
d=(d+)%;
return;
}
if(c==)
{
d=(d+)%;
return;
}
} inline bool is_legal(int x,int y)
{
return x> && x<=n && y> && y<=n && a[x][y]!='*';
} void solve()
{
memset(dp,0x3f,sizeof(dp));
memset(vis,-,sizeof(vis));
dp[][x0][y0][]=;
vis[][x0][y0][]=;
for(int i=;i<m;i++)
{
for(int x=;x<=n;x++)
{
for(int y=;y<=n;y++)
{
if(a[x][y]!='*')
{
for(int d=;d<;d++)
{
if(vis[i&][x][y][d]==i)
{
int temp;
if(vis[(i+)&][x][y][d]!=i+) temp=INF;
else temp=dp[(i+)&][x][y][d];
dp[(i+)&][x][y][d]=min(temp,dp[i&][x][y][d]+);
vis[(i+)&][x][y][d]=i+;
int nx=x,ny=y,nd=d;
cal_pos(nx,ny,nd,c[i]);
if(is_legal(nx,ny))
{
if(vis[(i+)&][nx][ny][nd]!=i+) temp=INF;
else temp=dp[(i+)&][nx][ny][nd];
dp[(i+)&][nx][ny][nd]=min(temp,dp[i&][x][y][d]);
vis[(i+)&][nx][ny][nd]=i+;
}
}
}
}
}
}
}
ans=m;
for(int x=;x<=n;x++)
{
for(int y=;y<=n;y++)
{
if(a[x][y]!='*')
{
for(int d=;d<;d++)
{
if(vis[m&][x][y][d]==m)
{
ans=min(ans,dp[m&][x][y][d]);
}
}
}
}
}
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}
RQNOJ 342 最不听话的机器人:网格dp的更多相关文章
- [Luogu P1006]传纸条 (网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P1006 Solution 挺显然但需要一定理解的网络(应该是那么叫吧)DP 首先有一个显然但重要的结论要发 ...
- rqnoj-342-最不听话的机器人-dp
dp[i][j][k][[l]: 执行第i步,执行到点(j,k),方向为l时,用的最大步数. 状态转移根据step[i]转移. #include<stdio.h> #include< ...
- RQNOJ 311 [NOIP2000]乘积最大:划分型dp
题目链接:https://www.rqnoj.cn/problem/311 题意: 给你一个长度为n的数字,用t个乘号分开,问你分开后乘积最大为多少.(6<=n<=40,1<=k&l ...
- RQNOJ 622 最小重量机器设计问题:dp
题目链接:https://www.rqnoj.cn/problem/622 题意: 一个机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得. w[i][j]是从供应商j处购得的部件i的重量, ...
- 1088. [SCOI2005]扫雷Mine【网格DP】
Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子 ...
- 1084. [SCOI2005]最大子矩阵【网格DP】
Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵 不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤ ...
- [Luogu P4147] 玉蟾宫 (网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P4147 Solution 裸的求极大子矩阵 感谢wzj dalao的教学 首先,有一个很显然但很重要的结论 ...
- 【原创】POJ 1703 && RQNOJ 能量项链解题报告
唉 不想说什么了 poj 1703,从看完题到写完第一个版本的代码,只有15分钟 然后一直从晚上八点WA到第二天早上 最后终于发现了BUG,题目要求的“Not sure yet.”,我打成了“No s ...
- 五大常见算法策略之——动态规划策略(Dynamic Programming)
Dynamic Programming Dynamic Programming是五大常用算法策略之一,简称DP,译作中文是"动态规划",可就是这个听起来高大上的翻译坑苦了无数人 ...
随机推荐
- Python将JSON格式数据转换为SQL语句以便导入MySQL数据库
前文中我们把网络爬虫爬取的数据保存为JSON格式,但为了能够更方便地处理数据.我们希望把这些数据导入到MySQL数据库中.phpMyadmin能够把MySQL数据库中的数据导出为JSON格式文件,但却 ...
- MQTT---HiveMQ源代码具体解释(十四)Persistence-LocalPersistence
源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 简单介绍 HiveMQ的Persistence提供配置包含File和Memory,以解决 ...
- [ACM] HDU 5024 Wang Xifeng's Little Plot (构造,枚举)
Wang Xifeng's Little Plot Problem Description <Dream of the Red Chamber>(also <The Story of ...
- 1、C++的的升级
1.C语言的缺点 (1)重用性差 (2)维护性差 2.C++ 从面向世界的需求出发来设计我们的程序, 3. 使用增强 A. ; i < ; i++) { } C语言编译器的话,会报错,因为C语言 ...
- Redis主从同步分析
一.Redis主从同步原理1.1 Redis主从同步的过程配置好slave服务器连接的master后,slave会建立和master的连接,然后发送sync命令.无论是第一次同步建立的连接还是连接断开 ...
- mybatis数据查询返回值
查询: 返回值是整数. 小于0是查询的数据不存在,大于0是查询的数据已经存在. 修改: 返回值是整数. 大于0是修改的数据成功,否则就是失败. 添加: 和修改同理.
- 将C#文档注释生成.chm帮助文档(转)
由于最近需要把以前的一个项目写一个文档,但一时又不知道写成怎样的,又恰好发现了可以生成chm的工具,于是乎我就研究了下,感觉还不错,所以也给大家分享下.好了,不多废话,下面就来实现一下吧. 生成前的准 ...
- 记一次Oracle数据故障排除过程
前天在Oracle生产环境中,自己的存储过程运行时间超过1小时,怀疑是其他job运行时间过长推迟了自己job运行时间,遂重新跑job,发现同测试环境的确不同,运行了25分钟. 之后准备在测试环境中制造 ...
- java中BigDecimal的学习
干着java的活,但是看的都是一些偏底层的东西(或者我根本就没有看),有点荒废了java的学习. 最近一直在用到一个类是BigDecimal,但都是模棱两可地在那儿用,并没有深入研究这个类的细节,感觉 ...
- 阿里云Opensearch数据类型
阿里云主要支持以下数据类型,详情参考:https://help.aliyun.com/document_detail/29121.html 类型 说明 INT int64整型 INT_ARRAY in ...