• 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;
    }
    
  • 相关阅读:
    SQL Server 查看新建、重建、重组索引进度
    CentOS PostgreSQL 12 主从复制(主从切换)
    CentOS PostgreSQL 12 安装
    SQL Server 当前事务无法提交,而且无法支持写入日志文件的操作。
    MySQL 碎片整理
    MySQL 5.7 MHA(mha4mysql-manager依赖包)
    MySQL- 5.7 sys schema
    MySQL InnoDB 恢复(recovery)详细流程
    MySQL学习(二十五)order by 逻辑
    jvm学习(一)DirectByteBuffer堆外内存浅析
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/5538289.html
Copyright © 2020-2023  润新知