微軟2016校園招聘4月線上筆試 hihocoder 1290 Demo Day (dp)

_TCgogogo_發表於2016-04-07
時間限制:10000ms
單點時限:1000ms
記憶體限制:256MB

描述

You work as an intern at a robotics startup. Today is your company's demo day. During the demo your company's robot will be put in a maze and without any information about the maze, it should be able to find a way out.

The maze consists of N * M grids. Each grid is either empty(represented by '.') or blocked by an obstacle(represented by 'b'). The robot will be release at the top left corner and the exit is at the bottom right corner.

Unfortunately some sensors on the robot go crazy just before the demo starts. As a result, the robot can only repeats two operations alternatively: keep moving to the right until it can't and keep moving to the bottom until it can't. At the beginning, the robot keeps moving to the right.

rrrrbb..            
...r....     ====> The robot route with broken sensors is marked by 'r'. 
...rrb..
...bb...

While the FTEs(full-time employees) are busy working on the sensors, you try to save the demo day by rearranging the maze in such a way that even with the broken sensors the robot can reach the exit successfully. You can change a grid from empty to blocked and vice versa. So as not to arouse suspision, you want to change as few grids as possible. What is the mininum number?

輸入

Line 1: N, M.

Line 2-N+1: the N * M maze.


For 20% of the data, N * M <= 16.

For 50% of the data, 1 <= N, M <= 8.

For 100% of the data, 1<= N, M <= 100.

輸出

The minimum number of grids to be changed.

樣例輸入
4 8
....bb..
........
.....b..
...bb...
樣例輸出
1

題目連結:http://hihocoder.com/problemset/problem/1290

題目大意:一個機器人從左上要走到右下,每次先一直往右走,被擋了就一直往下走,'b'為障礙,每個點可以把'b'變成'.',也可以把'.'變成'b',問使得機器人按規則走到終點最少要改變幾個點的狀態

題目分析:dp[i][j][k]表示走到點(i, j)方向為k (0為右,1為下)時所要改變的最小次數,狀態轉移的時候如果本來就有b擋著那可以直接轉,否則要轉的話次數要加1,因為相當於改變一個'.'的狀態來讓它轉向,初始狀態dp[1][1][0] = 0

#include <cstdio>
#include <algorithm>
using namespace std;
int const MAX = 1e2 + 5;
int n, m;
int dp[MAX][MAX][2]; //0 -> 右, 1 -> 下
char s[MAX][MAX];

int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++)
		scanf("%s", s[i] + 1);
	for(int i = 0; i <= n; i++)
		for(int j = 0; j <= m; j++)
			dp[i][j][0] = dp[i][j][1] = 0x3fffffff;
	dp[1][1][0] = 0;
	for(int i = 1; i <= n; i++)
	{
		for(int j = 1; j <= m; j++)
		{	
			if(i == 1 && j == 1)
				continue;
			dp[i][j][1] = dp[i - 1][j][1];
			if(s[i - 1][j + 1] == 'b' || j == m)
				dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j][0]);
			else
				dp[i][j][1] = min(dp[i][j][1], dp[i - 1][j][0] + 1);
			dp[i][j][0] = dp[i][j - 1][0];
			if(s[i + 1][j - 1] == 'b' || i == n)
				dp[i][j][0] = min(dp[i][j][0], dp[i][j - 1][1]);
			else
				dp[i][j][0] = min(dp[i][j][0], dp[i][j - 1][1] + 1);
			if(s[i][j] == 'b')
			{
				dp[i][j][0] ++;
				dp[i][j][1] ++;
			}
		}
	}
	printf("%d\n", min(dp[n][m][0], dp[n][m][1]));
}	


相關文章