码迷,mamicode.com
首页 > 其他好文 > 详细

hihocoder #1290 : Demo Day

时间:2016-04-09 23:39:42      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:

传送门

#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

 

 

1290 Demo Day AC G++ 0ms 0MB 1分钟前 查看

 

题解:

转自:http://www.cnblogs.com/acSzz/p/5362865.html

题目的意思是:
给你一个矩阵由‘.’和‘b‘组成 ‘.’表示可以走,‘b‘表示障碍物,机器人只能往右走直到不能走(碰到障碍物或者到头)和往下走直到不能走,两个方向,起始点是左上角,出口是右下角,为了机器人
能够走到出口,你可以将‘.‘变为‘b‘, 也可以将‘b‘变为‘.‘,,求为了使机器人走到出口,最少的变换次数。
(机器人从起点,一开始是往右走的,记住!!!!!!!)

思路:
应该算是动态规划吧,对于每一个点,到达这个点只能是经过上方点,或者从左方点到达该点,那么对于每一个点,一开始想的是用f[i][j],表示到达(i,j)需要变动的最小次数,但是发现到达每一个点是有方向的
,而且如果只用f[i][j],表示到达(i,j)的最小变动次数,不知道方向的话是无法递推下一个点的,所以,
我们用up[i][j],表示从上方到达该点需要变动的最小次数,r[i][j]表示从左方到达该点需要变动的最小次数,
  (i-1,j) (i - 1,j+1)
  (i,j)  
 对于up[i][j],可以是从左方到达(i-1, j),再到达(i,j),但此时(i-1, j+1)必须为‘b‘或者边界,也可以从上方到达(i-1,j)再到达(i,j);
还有就是如果(i,j)本身为‘b‘的话,则需要up[i][j]+1;

up[i-1][j]
up[i][j] = min
r[i-1][j] + 1(如果(i-1,j)不为‘b’或者边界则需要+1);


同理可得:

up[i][j-1] (+1) (如果(i+1,j-1)不为‘b‘或者边界,则需要+1)
r[i][j] = min
r[i][j-1]

为了处理方便在输入时,在矩阵的最右边和最下边添加了一行,一列‘b‘;


代码:

核心转移方程:
int dp[N][N][3];    //0xia,1you
int checkxia(int x,int y)
{
    if(x == n) return 0;
    if(s[x+1][y] == b) return 0;
    else return 1;
}

int checkyou(int x,int y)
{
    if(y == m) return 0;
    if(s[x][y+1] == b) return 0;
    else return 1;
}
                fxia = checkxia(i,j);
                fyou = checkyou(i,j);

                dp[i][j][0] += min(dp[i-1][j][0],dp[i][j-1][1] + fyou);
                dp[i][j][1] += min(dp[i][j-1][1],dp[i-1][j][0] + fxia);        

 



 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <string>
 6 #include <cstring>
 7 #include <vector>
 8 
 9 #define N 105
10 #define ll long long
11 #define inf 0x3fffffff
12 
13 using namespace std;
14 
15 int n,m;
16 int dp[N][N][3];    //0xia,1you
17 char s[N][N];
18 
19 int checkxia(int x,int y)
20 {
21     if(x == n) return 0;
22     if(s[x+1][y] == b) return 0;
23     else return 1;
24 }
25 
26 int checkyou(int x,int y)
27 {
28     if(y == m) return 0;
29     if(s[x][y+1] == b) return 0;
30     else return 1;
31 }
32 
33 int main()
34 {
35     //freopen("in.txt","r",stdin);
36     int i,j,k;
37     int fxia,fyou;
38     while(scanf("%d%d",&n,&m)!=EOF)
39     {
40         for(i=0;i<=n+1;i++){
41             for(j=0;j<=m+1;j++){
42                 for(k=0;k<=1;k++){
43                     dp[i][j][k]=inf;
44                 }
45             }
46         }
47         for(i = 1;i <= n ;i++){
48             scanf("%s",s[i]+1);
49         }
50         for(i = 1;i <= n;i++){
51             for(j = 1;j <= m;j++){
52                 fxia = checkxia(i,j);
53                 fyou = checkyou(i,j);
54                 for(k = 0 ;k <= 1;k++){
55                     dp[i][j][k] = 0;
56                     if(s[i][j] == b){
57                         dp[i][j][k] = 1;
58                     }
59                 }
60                 if(i == 1 && j== 1){
61                     dp[i][j][0] = dp[i][j][1] + fyou;
62                     continue;
63                 }
64                 dp[i][j][0] += min(dp[i-1][j][0],dp[i][j-1][1] + fyou);
65                 dp[i][j][1] += min(dp[i][j-1][1],dp[i-1][j][0] + fxia);
66             }
67         }
68     /*
69         for(i = 1;i <= n;i++){
70             for(j = 1;j <= m;j++){
71 
72                 for(k = 0 ;k <= 1;k++){
73                     printf(" i =%d j=%d k=%d dp=%d\n",i,j,k,dp[i][j][k]);
74                 }
75 
76             }
77         }*/
78         printf("%d\n",min(dp[n][m][0],dp[n][m][1]));
79     }
80     return 0;
81 }

 

hihocoder #1290 : Demo Day

标签:

原文地址:http://www.cnblogs.com/njczy2010/p/5372869.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!