(地图型dp 算路径条数)机器人走迷宫

 

题意:

给定 m 行 n 列的网格,机器人从左上角( 0 , 0 )出发,每次只可以向左或向下走一步,走到右下角位置,问有多少种走法?

输入样例:

2   3

输出样例:

3

确定末状态:

在某位置 ( x , y ) ,可以化为子问题由 ( x-1, y )向下走一步,或由 ( x,  y-1 )向右走一步,这两个子问题相加就是走到 ( x , y )的方法

状态方程:

dp[ i ][ j ]=dp[ i-1][ j ]+dp[ i ][ j-1 ]

初始状态和边界情况:

初始状态及边界情况,在格子( i,0) 和( 0 , j )的地方都只有一种情况到达,即 i==0或 j==0 dp[ i ][ j ]=1

#include<iostream>
#include<string.h>
#include<math.h>

using namespace std;
int n,m,v; 
int ans;
int mod=1e9+7;
int dp[105][105];
bool vis[105]; 

int main(){
    cin>>n>>m;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(i==0||j==0){
                dp[i][j]=1;
            }
            else{
                dp[i][j]=dp[i-1][j]+dp[i][j-1];           //因为考虑了 i=0 和 j=0 的情况,则 i-1和 j-1就不存在越界了 
            }
        }
    }
    cout<<dp[n-1][m-1];
    return 0;
}

 进一步的,给k个格子,使这些格子有障碍,不能到达这些格子,问这种情况下到右下角的总数

输入样例:

3  3  1

1  1

输出样例:

2

#include<iostream>
#include<string.h>
#include<math.h>

using namespace std;
int n,m,v; 
int ans;
int mod=1e9+7;
int dp[105][105];
bool vis[105]; 

int main(){
    cin>>n>>m>>v;
    int x,y;
    for(int i=0;i<v;i++){
        cin>>x>>y;
        dp[x][y]=-1;
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(dp[i][j]!=-1){                       //该格子必须可以到达 
                if(i==0||j==0){
                    dp[i][j]=1;
                }
                else{                              //因为考虑了 i=0 和 j=0 的情况,则 i-1和 j-1就不存在越界了 
            dp[i][j]=0; if(dp[i-1][j]!=-1){ //考虑左边一个格子是不是有障碍 无障碍则可以从该格子走 dp[i][j]+=dp[i-1][j]; } if(dp[i][j-1]!=-1){ //考虑右边一个格子是不是有障碍 无障碍则可以从该格子走 dp[i][j]+=dp[i][j-1]; } } } } } cout<<dp[n-1][m-1]; return 0; }

 更进一步的:

给定 m 行 n 列的网格,每个格子上有一个值,机器人从左上角( 0 , 0 )出发,每次只可以向左或向下走一步,走到右下角位置,问走过路径和最小值是多少?

输入样例:

3  5

1   5   7   6   8

4   7   4   4   9

10 3   2   3   2

输出样例:

15

#include<iostream>
#include<string.h>
#include<math.h>

using namespace std;
int n,m,v; 
long ans;
int mod=1e9+7;
int dp[105][105],aa[105][105];
bool vis[105]; 

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>aa[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i==1&&j!=1){
                dp[i][j]=dp[i-1][j]+aa[i][j];                      // i或j为1只有一种走法,为边界情况 
            }
            else if(i!=1&&j==1){
                dp[i][j]=dp[i][j-1]+aa[i][j];
            }
            else{
                dp[i][j]=min(dp[i-1][j],dp[i][j-1])+aa[i][j];     //从左边或上面的最小值到该格子 
            }
        }
    }
    cout<<dp[n][m];
    return 0;
}

 

posted @ 2020-03-14 10:37  Maxwell·  阅读(433)  评论(0编辑  收藏  举报