您的位置:首页 > 其它

来自风平浪静的明天 (记忆化搜索 dp)

2017-09-18 08:48 155 查看

来自风平浪静的明天

【题目描述】

冬眠了五年,光终于从梦中醒来。

千咲、要,大家都在。

隐约记得“昨天”的海船祭,爱花意外成为贡女,沉入海底。

海面冰封,却有丝丝暖流在冰面之下涌动。

此时,爱花沉睡在祭海女神的墓地。她的胞衣在一点点脱落,化作一簇簇暖流,夹杂着她的感情,向海面上涌去。

爱花,你在哪里?

五年之后,纺已经成为海洋学研究科的大学生。

在纺的帮助下,光得知了海面下海流的情况。

纺告诉光,暖流一旦产生,就会不断地向四周扩散,直到遇到海中的岩石。

红腹海牛,快告诉光,爱花在哪里。

纺帮你绘制了一张海流情况图,长度为N,宽度为M。

海很大,一边有沙滩,一边一望无际,但长度和宽度都不会超过300。沙滩是金黄色的,所以用Y表示。海是蓝色的,所以用B表示。暖流很暖和,所以用H表示

海中有大大小小的石头。石头很危险,所以用X表示

光相信自己一定能找到爱花(爱花的位置只有一种可能)

【输入格式】

第一行包括两个整数N,M。

接下来N行,每行M个字符。

【输出格式】

仅一行,表示爱花的位置(如果你无能为力,请输出 -1 ,只要你尽力,光不会责怪你)

【样例输入】

5 5

YYYHB

YYHHH

YHHXB

BBHBB

BBBBB

【样例输出】

2 3

【数据范围】

对于30%的数据,n,m<=10

对于70%的数据,n,m<=100

对于100%的数据,n,m<=300

【样例解释】

在(2,3)出现第一个H后,经过3s后,出现样例输入的地图。

P.S. Mushroom拜托他GF出的这题= =

思路:

看看数据范围,应该是一个n^3的算法,x,y一枚举就n^2了,然后。。。发现H最多就会漫延n+m次。

用dp[step][x][y]表示当前在(x,y),还要走step步是否能达到目标局面,也就是说是个bool。

那么对于当前这个点,如果是’B’并且step!=0那么当前状态显然是false,如果是石头或者沙滩,那么是true,如果当前step==0,那么返回(g[x][y]==’H’)。

数据太水,暴力dfs可过。。。

std的题解:

Solution

还记得以前解决过的那个问题吗?

水从一个点开始向四周漫去,一定时间后是什么样子?

显然是简单的模拟。

这次的问题正好相反,要找到水开始漫的位置。

Solution1

看了半天,什么也没发现。

天空突然电闪雷鸣,一个神奇的想法也就出现了。

YYYHB

YYHHH

YHHXB

BBHBB

BBBBB

这四个地方就是暖流的边界。

只有周围的四个格子是蓝蓝的大海或者石头和沙滩,才可能是暖流的边界。

我们可以把这些边界放进一个队列里,然后把图上变成大海。

YYYBB

YYHHB

YBHXB

BBBBB

BBBBB

然后就有了新的边界。

如此反复,最后剩下的暖流就是爱花的位置。

YYYBB

YYHBB

YBBXB

BBBBB

BBBBB

原来找到爱花这么容易。

时间复杂度O(N^2)

空间复杂度O(N^2)

恩,如果大海的结构这么简单的话,的确如此。

又看了半天,不得不佩服大海的深邃。

YYYHB

YYHHH

YHHXB

YXHXB

YYYYY

我们用之前的方法

YYYHB

YYHHH

YHHXB

YXHXB

YYYYY

放进队列,然后把它们变成大海

YYYBB

YYHHB

YHHXB

YXHXB

YYYYY

YYYBB

YYBBB

YHBXB

YXHXB

YYYYY

然后就成了这样,有两个位置看起来像是爱花所在的地方。

但事实并非如此。

YYYHB

YYHHH

YHHXB

YXHXB

YYYYY

爱花其实在这里。

Solution2

又想了半天。

看起来可以DP。

Flow[TIME][X][Y]表示暖流的初始位置是(X,Y),经过时间TIME以后,形成的图案会不会和海流图不相符(不应是H的地方出现了H则不相符,应出现H的地方没有出现H认为相符)

YYYHB

YYHHH

YHHXB

BBHBB

BBBBB

海流图

YYYBB

YYHHB

YBHXB

BBBBB

BBBBB

相符的图(蓝色部分应该出现H但没有出现)

YYYHH

YYHHH

YHHXH

BHHHB

BBHBB

不相符的图(红色部分不该出现H但出现了)

F[TIME][X][Y]=F[TIME-1][X-1][Y]&&F[TIME-1][X][Y-1]&&F[TIME-1][X+1][Y]&&F[TIME-1][X][Y+1]

记忆化DP 时间复杂度O(N^3) 空间复杂度 O(N^3)

找到最大的TIME,对应的X和Y就是爱花的位置。

因为光相信自己一定能找到爱花,所以爱花的位置确定(不会有两个位置满足条件)。

Solution3

更好的算法?

还得继续想吧。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;

const int N = 305;

char map

;
bool f[N<<1]

[2];//f[T][x][y]表示设x,y是张ansT     即牺
char ss
;
int n,m;

bool check(int T, int x, int y){
if( f[T][x][y][0] ) return f[T][x][y][1];
if(x==0 || y==0 || x==n+1 || y==m+1) return true;
if(map[x][y] != 'H') return true;
f[T][x][y][0] = true;
if(T == 0) return f[T][x][y][1] = true;
if(map[x-1][y]=='B' || map[x+1][y]=='B' || map[x][y-1]=='B' || map[x][y+1]=='B')
return f[T][x][y][1] = false;
f[T][x][y][1] = check(T-1,x-1,y) && check(T-1,x+1,y) && check(T-1,x,y-1) && check(T-1,x,y+1);
return f[T][x][y][1];
}

int main(){
freopen ("calm.in", "r", stdin);
freopen ("calm.out", "w", stdout);
scanf("%d%d", &n, &m);
for(register int i=1; i<=n; i++){
scanf("%s", ss);
for(register int j=1; j<=m; j++)
map[i][j] = ss[j-1];
}
for(register int t=n+m; t>=1; t--)
for(register int i=1; i<=n; i++)
for(register int j=1; j<=m; j++){
if(map[i][j] == 'H') check(t, i, j);
if( f[t][i][j][1] ){
printf("%d %d", i, j);
return 0;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: