hihocoder 1290:Demo Day

#1290 : Demo Day

时间限制: 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
题意就是机器人能往右走就往右走,不能就往下走。往下走走不动了就再往右走。你能够把障碍物变成平地,也能把平地变成障碍物。问机器人从图的左上走到右下的话,最少需要修改图中的几个格子。

DP。dp[x][y][0]表示从该格子左边走的代价,dp[x][y][1]表示该格子右边走的代价。递推。

代码:

#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;

#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))

const ll mod = 100000007;
const int maxn = 105;
const double PI = acos(-1.0);

int n, m;
char val[maxn][maxn];
int dp[maxn][maxn][2];

void solve()
{
	int i, j, k;
	memset(val, 0, sizeof(val));

	for (i = 1; i <= n; i++)
	{
		scanf("%s", val[i] + 1);
	}
	memset(dp, -1, sizeof(dp));

	if (val[1][1] == '.')
	{
		dp[1][1][0] = 0;
	}
	else
	{
		dp[1][1][0] = 1;
	}
	if (m == 2 || val[1][2] == 'b')
	{
		dp[1][1][1] = 0;
	}
	else
	{
		dp[1][1][1] = 1;
	}

	for (i = 1; i <= n; i++)
	{
		for (j = 1; j <= m; j++)
		{
			if (i == 1 && j == 1)
				continue;
			if (j == 1)
			{
				if (i == n || val[i + 1][j] == 'b')
				{
					dp[i][j][0] = dp[i - 1][j][1];
				}
				else
				{
					dp[i][j][0] = dp[i - 1][j][1] + 1;
				}
				dp[i][j][1] = dp[i - 1][j][1];
				if (val[i][j] == 'b')
				{
					dp[i][j][0]++, dp[i][j][1]++;
				}
			}
			else
			{
				dp[i][j][0] = dp[i][j - 1][0];
				if (val[i][j] == 'b')
				{
					dp[i][j][0]++;
				}
				if (i > 1)
				{
					int t = dp[i - 1][j][1];
					if (val[i][j] == 'b')t++;
					if (i == n || val[i + 1][j] == 'b')
					{
						dp[i][j][0] = min(t, dp[i][j][0]);
					}
					else
					{
						dp[i][j][0] = min(t + 1, dp[i][j][0]);
					}
				}

				dp[i][j][1] = dp[i][j - 1][0];
				if (val[i][j] == 'b')dp[i][j][1]++;
				if (!(j == m || val[i][j + 1] == 'b'))
					dp[i][j][1]++;
				if (i > 1)
				{
					int t = dp[i - 1][j][1];
					if (val[i][j] == 'b')
					{
						t++;
					}
					dp[i][j][1] = min(dp[i][j][1], t);
				}
			}
		}
	}

	printf("%d\n", min(dp[n][m][1], dp[n][m][0]));
}

int main()
{

	while (scanf("%d%d", &n, &m) != EOF)
	{
		solve();
	}

	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值