题目大意

一个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的更多相关文章

随机推荐

  1. 基于SURF特征的图像与视频拼接技术的研究和实现(一)

    基于SURF特征的图像与视频拼接技术的研究和实现(一)      一直有计划研究实时图像拼接,但是直到最近拜读西电2013年张亚娟的<基于SURF特征的图像与视频拼接技术的研究和实现>,条 ...

  2. 最流行的编程语言JavaScript能做什么?

    本文转自互联网! 首先很遗憾的一点是,"PHP虽然是最好的语言",但是它不是最流行的语言. 对不起的还有刚刚在4月TIOBE编程语言排行榜上榜的各个语言: 你们都很棒,但是你们都担 ...

  3. Java过滤器应用-对Ajax请求做Session失效判断

    过滤器常用来对Session过期做判断 Layout.js 1.为ajax请求添加标识 2.无论ajax请求成功与否,complete函数终会执行 // 全局Ajax设置, 用于session过期后的 ...

  4. c#启动EXE文件(简单的)

    在程序执行中会遇到启动本软件的exe问,或者启用其它的exe文件,已达到执行某些操作的作用.下面是两种最常见的启动exe文件. 1.调用系统dll使用其提供的方法. 引用的dll, [DllImpor ...

  5. .Net大文件上传(转--待验证)

    几种常见的方法,本文主要内容包括:    第一部分:首先我们来说一下如何解决ASP.net中的文件上传大小限制的问题,我们知道在默认情况下ASP.NET的文件上传大小限制为2M,一般情况下,我们可以采 ...

  6. .Net文件*夹*操作

    一.文件夹操作 Directory类,DirectoryInfo类.使用using System.IO命名空间 (一)创建文件夹 方法一: private string path = @"F ...

  7. Spring 框架 详解 (四)------IOC装配Bean(注解方式)

    Spring的注解装配Bean Spring2.5 引入使用注解去定义Bean @Component  描述Spring框架中Bean Spring的框架中提供了与@Component注解等效的三个注 ...

  8. Spring MVC 详解(二)

    前端控制器 在web.xml中配置: 在springmvc.xml中配置springmvc架构三大组件(处理器映射器.适配器.视图解析器) 处理器映射器 在springmvc.xml中配置: Bean ...

  9. CodeForces 146A Lucky Ticket

    Lucky Ticket Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submi ...

  10. 正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ?

    正则表达式(/[^0-9]/g,'')中的"/g"是什么意思 ?     表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义.我们详细叙述: 1)对于表达式对象的e ...