hiho 1290 2016微软4月笔试 dp

来源:互联网 发布:共产主义社会 知乎 编辑:程序博客网 时间:2024/05/19 20:21

题目大意:给你一个机器人,从左上角走到右下角需要的最少改变格子的次数。格子有.代表空和b代表障碍物组成,可以b变.,也可以.边b。


思路:dp[i][j][0]表示当前节点向下走到终点需要的最少改变次数,dp[i][j][1]表示当前节点向右走走到终点的最少改变次数。

那么如果当前点需要向右走,就需要判断右面点的dp值哪一个更小,1、如果需要转弯则需要再往右判断一位,如果是b或边界则 dp[i][j][1] = dp[i][j+1][0];否则dp[i][j][1] = dp[i][j+1][0] + 1;2、不需要转弯dp[i][j][1] = dp[i][j+1][1];

向下走同理!


ps:当晚笔试忽略了 vice versa (反之亦然) , 第二天被起始格子的值坑了,如果他有b也当‘.’算,所以最后递推输出时需要判断一下a[1][2];

对于英语,也是醉了。


#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <fstream>#include <algorithm>#include <cmath>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <iomanip>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define maxn 205#define MOD 1000000007#define mem(a , b) memset(a , b , sizeof(a))#define LL long longconst long long INF=0x3fffffff;int dp[110][110][2];char a[110][110];int main(){    int n , m;    while(scanf("%d %d" , &n , &m)!= EOF)    {        for(int i = 1 ; i <= n ; i ++)        {            scanf("%s" , a[i]+1);        }        a[1][1] = '.';        //cout << a[n][m] << endl;        if(a[n][m] == 'b')            dp[n][m][0] = dp[n][m][1] = 1;        else            dp[n][m][0] = dp[n][m][1] = 0;        int cnt = 0;        if(a[n][m] == 'b') cnt ++;        for(int i = n-1 ; i >= 1 ; i --)        {            if(a[i][m] == 'b') cnt ++;            dp[i][m][0] = dp[i][m][1] = cnt;        }        cnt = 0;        if(a[n][m] == 'b') cnt ++;        for(int i = m-1 ; i >= 1 ; i --)        {            if(a[n][i] == 'b') cnt ++;            dp[n][i][0] = dp[n][i][1] = cnt;        }        for(int i = n-1 ; i >= 1 ; i --)        {            for(int j = m-1 ; j >= 1 ; j --)            {                if(dp[i][j + 1][1] > dp[i][j+1][0])   //右边走下一个要转弯                {                    if(j+1==m || a[i][j+2] == 'b') dp[i][j][1] = dp[i][j+1][0];                    else dp[i][j][1] = dp[i][j+1][0] + 1;                }                else dp[i][j][1] = dp[i][j+1][1];                if(dp[i+1][j][0] > dp[i+1][j][1])   //下边走下一个要转弯                {                    if(i+1==n || a[i+2][j] == 'b') dp[i][j][0] = dp[i+1][j][1];                    else dp[i][j][0] = dp[i+1][j][1] + 1;                }                else dp[i][j][0] = dp[i+1][j][0];                if(a[i][j] == 'b') dp[i][j][0]++ , dp[i][j][1] ++;            }        }       // int ans = min(dp[1][1][0] , dp[1][1][1]);        int ans ;        if(dp[1][1][0] < dp[1][1][1] && m > 1 && a[1][2] == 'b') ans = dp[1][1][0];        else ans = dp[1][1][1];       // if(a[1][1] == 'b') ans --;       // if(a[n][m] == 'b') ans ++;        printf("%d\n" , ans);    }    return 0;}


0 1
原创粉丝点击