小红闯沼泽地(动态规划,BFS)

 

链接:https://ac.nowcoder.com/acm/contest/72779/C
来源:牛客网

小红来到了一片沼泽地的岸边,她希望能通过这片沼泽地。
这个沼泽地地图用一个矩阵进行表示。1代表沼泽,0代表平地。小红刚开始在矩阵的左上角,她需要从右下角离开地图。已知进入地图和离开地图的时间可以忽略。小红可以向左、向右或者向下走。
当小红从沼泽进入沼泽,或者平地进入平地时,需要花费1单位时间。
当小红从沼泽进入平地,或者平地进入沼泽时,由于需要更换装备,所以要花2单位时间。
小红可以从左上角进入地图,从右下角离开地图。
小红想知道,经过这片沼泽地,最少需要花费多少单位时间。
输入描述:
第一行输入两个正整数 n 和 m,用空格隔开,代表矩阵的行数和列数。
接下来的n行,每行输入m个正整数ai,j,用来表示矩阵。
2n,m2000
输出描述:
输出一个正整数,代表经过沼泽地的最少时间。
示例1
输入
3 3
1 0 0
1 1 1
0 0 1
输出
4
说明
从左上角进入,往下走一次,往右走兩次,往下走一次,到右下角。花费4单位时间。
可以证明,这样花费的时间一定是最小的。

dp

和我们之前以往做的不同的是它可以向右走,所以我们对于一列的时候,我们正着遍历一遍之后,反着再遍历一遍

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
const int N=2010;
int n,m,a[N][N],dp[N][N];

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
            scanf("%d",&a[i][j]);
        }
    }

    memset(dp,0x3f,sizeof dp);
    
    dp[1][1]=0;
    for(int i=1;i<=n;i++){
    	for(int j=1;j<=m;j++){
    		if(i==1 && j==1) continue;
    		if(i==1){
    			dp[i][j]=dp[i][j-1]+(a[i][j]==a[i][j-1]?1:2);
    		}
    		else if(j==1){
    			dp[i][j]=dp[i-1][j]+(a[i][j]==a[i-1][j]?1:2);
    		}
    		else{
    			dp[i][j]=min(dp[i][j-1]+(a[i][j]==a[i][j-1]?1:2),dp[i-1][j]+(a[i][j]==a[i-1][j]?1:2));
    		}
        }
        for(int j=m;j>=1;j--){
            if(j!=m) dp[i][j]=min(dp[i][j],dp[i][j+1]+(a[i][j]==a[i][j+1]?1:2));
        }
    }
    printf("%d",dp[n][m]);
	return 0;
}

BFS

这个BFS有点类似于最短路中贪心的思路

#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
/*
1代表沼泽,0代表平地
小红可以向左、向右或者向下走。
当小红从沼泽进入沼泽,或者平地进入平地时,需要花费1单位时间
当小红从沼泽进入平地,或者平地进入沼泽时,由于需要更换装备,所以要花2单位时间
*/
using namespace std;
const int maxn=2010;
int a[maxn][maxn],dis[maxn][maxn];
int n,m;
int dx[3]={0,0,1};
int dy[3]={1,-1,0};
int bfs(){
	queue<pair<int,int>>q;
	q.push({1,1});
	while(!q.empty()){
		auto top=q.front();
		q.pop();
		for(int i=0;i<3;i++){
			int xx=top.first+dx[i];
			int yy=top.second+dy[i];
			if(xx<1||xx>n||yy<1||yy>m) continue;
			int d=(a[top.first][top.second]==a[xx][yy]?1:2);
			if(dis[xx][yy]>dis[top.first][top.second]+d){
				dis[xx][yy]=dis[top.first][top.second]+d;
				q.push({xx,yy});
			}
		}
	}
}
int main(){
	cin>>n>>m;
	memset(dis,0x3f3f3f,sizeof(dis));
	dis[1][1]=0; 
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	bfs();
	cout<<dis[n][m]<<endl;
}
posted @   lipu123  阅读(34)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
历史上的今天:
2020-01-02 牛客新年AK场之模拟二维数组
2020-01-02 codeforces Beautiful Numbers
点击右上角即可分享
微信分享提示