记忆化搜索t3(沙漠绿洲)求助

题目描述:

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个 N 行 M 列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度。

为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。

因此,只有与湖泊毗邻的第 11 行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。由于第 N 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。

输入格式:

第一行两个整数 n 和 m,

接下来 n 行每行 m 个整数,表示海拔高度。

输出格式:

如果所有干旱区都可以得到水,则第一行输出 1,第二行输出最少的蓄水厂数量。

否则第一行输出 0,第二行输出有几个城市不可能有水。

样例输入:

2 5 9 1 5 4 3 8 7 6 1 2

样例输出:

1 1

样例输入:

3 6 8 4 5 6 4 4 7 3 4 3 3 3 3 2 2 1 1 2

样例输出:

1 3

数据规模:

n≥2,n,m≤500,海拔高度不超过10^6。

样例全过, 提交WA10

#include<bits/stdc++.h>
using namespace std;

const int N = 510;
int n, m, a[N][N];
int l[N][N], r[N][N], vis[N][N];
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

void dfs(int x, int y)
{
	vis[x][y] = 1;
	if(x == n)
	{
		l[x][y] = y;
		r[x][y] = y;
	}
	else
	{
		l[x][y] = m+1;
		r[x][y] = -1;
	}
	for(int i = 0; i < 4; i ++)
	{
		int nx, ny;
		nx = x + dir[i][0];
		ny = y + dir[i][1];
		if(nx < 1 || nx > n || ny < 1 || ny > m) continue;
		else if(a[nx][ny] >= a[x][y]) continue;
		if(!vis[nx][ny]) dfs(nx, ny);
		l[x][y] = min(l[x][y], l[nx][ny]);
		r[x][y] = max(r[x][y], r[nx][ny]);
	}
}

int main()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)
	{
		for(int j = 1; j <= m; j ++)
		{
			cin >> a[i][j];
		}
	}
	memset(vis, 0, sizeof(vis));
	for(int i = 1; i <= m; i ++)
	{
		if(vis[1][i] == 1) continue;
		else dfs(1, i);
	}
	int cnt = 0, flag = 1;
	for(int i = 1; i <= m; i ++)
	{
		if(vis[1][i] == 0)
			cnt ++, flag = 0;
	}
	int ans = 0;
	if(!flag)
		printf("0\n%d", cnt);
	else
	{
		int left = 1, right = 0, maxn = 0;
		cout << 1 << endl;
		while(right < m)
		{
			for(int i = 1; i <= m; i ++)
			{
				if(l[1][i] <= left && r[1][i] >= left)
				{
					maxn = max(maxn, r[1][i]);
				}
			}
			ans ++;
			right = maxn;
			left = maxn + 1;
			maxn = 0;
		}
		cout << ans;
	}
	
	return 0;
}
4 个赞

???
BDFS
???
(发源码危险哦!!!)

4 个赞

《别举报》

4 个赞

我只有30pts

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[3001][3001],vs[3001][3001],L[3001][3001],R[3001][3001];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,-1,1};
void dfs(int x,int y){
	vs[x][y]=true;
	for(int i=0;i<4;i++){
		int nx=x+dx[i];
		int ny=y+dy[i];
		if(nx<0||ny<0||nx>=n||ny>=m||a[nx][ny]>=a[x][y])continue;
		if(!vs[nx][ny])dfs(nx,ny);
		L[x][y]=min(L[x][y],L[nx][ny]);
		R[x][y]=max(R[x][y],R[nx][ny]);
	}
}
int main(){
	cin>>n>>m;
	int inf=0x3f3f3f3f;
	memset(L,inf,sizeof L);
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=0;i<m;i++){
		dfs(0,i);
	}
	int cnt=0;
	for(int i=0;i<m;i++){
		if(vs[n-1][i]==0)cnt++;
	}
	if(cnt>0){
		cout<<"0\n"<<cnt<<"\n";
	}
	else{
		cout<<"1\n";
		int l=0,r=0,res=0;
		while(l<m){
			for(int i=0;i<m;i++){
				if(L[0][i]<=l)r=max(r,R[0][i]);
			}
			l=r+1,res++;
		}
		cout<<res;
	}
	return 0;
}

3 个赞

%%%模

3 个赞