hiho_1290_demo_day
题目大意
一个MxN的矩阵,矩阵中的有些方格中有障碍物,有些没有,有一个机器人从左上角出发,它只能有两种移动方式:一直向右移动,直到遇到障碍物;一直向下移动,直到遇到障碍物。
现在可以将矩阵中的方格进行变换:如果方格中没有障碍物,则可以加入障碍物;如果方格中有障碍物,则可以清楚障碍物。求使得机器人可以从左上角移动到右下角的最少的方格变动个数。
题目链接: demo_day
题目分析
搜索复杂度太高,由于机器人只能向右或者向下移动,这就可以考虑使用动态规划进行状态的转移。设状态 dp[i][j][0] 表示robot从左侧进入方格(i,j)所需要改变的最少的方格数;dp[i][j]1表示robot从上侧进入方格(i, j)时所需要改变的最少的方格数。
这道题目是微软的暑期实习在线笔试题,考试期间做的时候由于对c/c++中的运算符优先级没有掌握准确,left_min + (gMap[i - 1][j - 1] == 'b') 中没有加括号,导致结果出错。基础很重要啊! 运算优先级不确定的地方,加括号!
另外,动态规划的初始值很重要,要仔细思考!
实现
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<stdio.h>
#include<stdint.h>
#include<string.h>
using namespace std;
#define MAX_NUM 105
char gMap[MAX_NUM][MAX_NUM]; int dp[MAX_NUM][MAX_NUM][2];
//dp[i][j][0] robot 从左侧进入(i, j)最少需要改变的次数
//dp[i][j][1] robot 从上册进入(i, j)最少需要改变的次数
#define INF 1 << 29 void debug(int m, int n){
for (int i = 1; i <= m; i++){
for (int j = 1; j <= n; j++){
cout << "(" << i << ", " << j << ", 0) = " << dp[i][j][0] << ", ";
cout << "(" << i << ", " << j << ", 1) = " << dp[i][j][1] << endl;
}
cout << endl;
}
}
int min(int a, int b){
return a < b ? a : b;
}
int main(){
int m, n;
scanf("%d %d", &m, &n);
for (int i = 0; i < m; i++){
getchar();
for (int j = 0; j < n; j++){
scanf("%c", &gMap[i][j]);
dp[i + 1][j + 1][0] = INF;
dp[i + 1][j + 1][1] = INF;
}
}
int count = 0;
for (int i = 1; i <= n; i++){
if (gMap[0][i - 1] == 'b')
count++;
dp[1][i][0] = count;
dp[1][i][1] = INF;
}
count = (gMap[0][1] != 'b');
for (int i = 1; i <= m; i++){
if (gMap[i - 1][0] == 'b')
count++;
dp[i][1][1] = count;
dp[i][1][0] = INF;
}
dp[1][1][0] = 0; for (int i = 2; i <= m; i++){
for (int j = 2; j <= n; j++){
int up_0 = dp[i - 1][j][0];
int up_1 = dp[i - 1][j][1];
int up_min = up_0 + !(j == n|| gMap[i - 2][j] == 'b');
up_min = min(up_min, up_1);
dp[i][j][1] = min(dp[i][j][1], up_min + (gMap[i - 1][j - 1] == 'b')); int left_0 = dp[i][j - 1][0];
int left_1 = dp[i][j - 1][1];
int left_min = left_1 + !(i == m || gMap[i][j - 2] == 'b');
left_min = min(left_min, left_0);
dp[i][j][0] = min(dp[i][j][0], left_min + (gMap[i - 1][j - 1] == 'b'));
}
}
int result = dp[m][n][0] < dp[m][n][1] ? dp[m][n][0] : dp[m][n][1];
cout << result << endl;
return 0;
}
hiho_1290_demo_day的更多相关文章
随机推荐
- HTML5之结构元素
1:文档结构元素 1.1 文章语义 -- article.header和footer元素 article元素在页面中用来表示结构完整且独立的内容部分,如论坛的一个帖子,杂志或者报纸的一篇文章. ar ...
- VS2010常用快捷键
ctrl + K, ctrl + F 自动调整格式(选中内容) F12 转到定义 ctrl + F12 转到声明 ctrl + tab 文档窗口转换(下一个文档窗口) alt + F6 下一个面板窗口 ...
- 2016年12月12日 星期一 --出埃及记 Exodus 21:7
2016年12月12日 星期一 --出埃及记 Exodus 21:7 "If a man sells his daughter as a servant, she is not to go ...
- sql重新排序
declare @i int select @i = 10 update dbo.T_StartEndCode set @i = @i+1,OrderNumber = @i
- Struts2的异常处理
Struts2的异常处理 1.异常处理机制(1)发送请求到控制器(Action); (2)Action出现异常后,依照所捕捉的不同异常转入不同的视图资源. 2.异常捕捉 (1)在Action的处理逻辑 ...
- SqlSever基础 order by之后再orderby,双重排序,对排序好的数据中再次进行排序
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- 达人眼中的WINCE网络驱动
实际上在WinCE上开发网络驱动,比如设计一个NIC驱动, 大多数情况,是从XP移植NDIS Miniport驱动(小端口驱动)到WinCE.什么是ndis?Ndis做什么用的? 什么是minipor ...
- 【leetcode❤python】231. Power of Two
#-*- coding: UTF-8 -*- class Solution(object): def isPowerOfTwo(self, n): if(n<=0): ...
- include_path详细解析
include_path详细解析 原文地址:http://www.laruence.com/2010/05/04/1450.html 1.php默认的包含路径为 .;C:\php\pear 即 ...
- Servlet&jsp基础:第四部分
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...