Space Tour (DP 或 记忆化搜索) Gym - 100541I

12 篇文章 0 订阅

题目链接:https://vjudge.net/problem/Gym-100541I

                                                          Space Tour

Alpha Centauri-M (ACM) is a planet with marvelous scenes for visitors from the Earth. Luckily you win a ticket to participate in a space tour to Alpha Centauri-M.

The map of the planet ACM is divided into a grid of M rows and N columns. The columns are indexed from 1 to N (from left to right) and the rows are indexed from 1 to M (from top to bottom). There are several cells on the map that are not safe for visitors to explore because of high mountains and volcanoes.

Upon arriving at ACM, the spaceship will land on any safe cell on the grid and passengers can visit the planet via a special system of space cars. From the landing cell (r0, c0) on the map, a space car can go to either one of the four connected adjacent cells, namely (r0–1, c0), (r0 + 1, c0), (r0, c0–1), (r0, c0 + 1). Subsequently, the space car will continue moving the following fixed navigation pattern:

  1. Turn right and go forward one cell
  2. Turn left and go forward one cell
  3. Go back to step 1.

A space car can only visit safe cells, therefore it will stop if the next cell is not safe or is beyond the map boundaries. The following figure illustrates a map consisting of M = 6 rows and N = 7 columns. From the landing cell (4, 3), you may visit 16 cells (including the landing cell).

For each landing cell on the map, you can determine the number of cells that you can visit (including the landing cell). Your task is to choose the landing cell from which you can visit the maximum number of cells on Alpha Centauri-M.

Input

The input file consists of several datasets. The first line of the input file contains the number of datasets which is a positive integer and is not greater than 20. The following lines describe the datasets.

The first line of a dataset contains 2 space-separated positive integers M and N (1 ≤ M, N ≤ 1000). The ith line in the next M lines of the dataset contains N binary digits to represent the states of all cells in the ith row of the map (1: safe cell, 0: unsafe cell).

Output

For each dataset, write in one line the maximum number of cells that you can visit on Alpha Centauri-M (including the landing cell).

Examples

Input

2
3 3
011
111
111
6 7
1101011
0111111
1111101
1111111
1111110
0111111

Output

8
20

 

思路:枚举每个点。

然后对四个方向进行DP(在每个方向的行为是一定的,该点所能到达的地方取决于两个点,进行dp) 或 记忆化搜索(pxgg做的,我以为搜索会超时没写,还是思考的不透彻) 

DP代码 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#define cla(a, sum) memset(a, sum, sizeof(a))
using namespace std;
typedef long long ll;
int T;
int n,m,ans;
const int maxn=1e3+5;
int a[maxn][maxn];
int up[maxn][maxn],le[maxn][maxn];
int down[maxn][maxn],ri[maxn][maxn];
void read()
{
	scanf("%d%d",&n,&m);
	int i,j;
	char ch;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;)
		{
			ch=getchar();
			if(ch=='0'){
				a[i][j]=0;j++;
			}
			else if(ch=='1'){
				a[i][j]=1;j++;
			}
		}
	}
}
void solve()
{
	cla(up,0);cla(le,0);
	cla(down,0);cla(ri,0);
	int i,j;
	//dp四个方向 
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(a[i][j]){
				up[i][j]=1;
				if(a[i-1][j]){
					up[i][j]=up[i-1][j+1]+2;
				}					
			}
		}
	}
	for(i=1;i<=m;i++)
	{
		for(j=1;j<=n;j++)
		{
			if(a[j][i]){
				le[j][i]=1;
				if(a[j][i-1]){
					le[j][i]=le[j-1][i-1]+2;
				}
			}
		}
	}
	for(i=n;i>=1;i--)
	{
		for(j=1;j<=m;j++)
		{
			if(a[i][j]){
				down[i][j]=1;
				if(a[i+1][j]){
					down[i][j]=down[i+1][j-1]+2;
				}
			}
		}
	}
	for(i=m;i>=1;i--)
	{
		for(j=1;j<=n;j++)
		{
			if(a[j][i]){
				ri[j][i]=1;
				if(a[j][i+1]){
					ri[j][i]=ri[j+1][i+1]+2;
				}
			}
		}
	}
	ans=0;
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(a[i][j])ans=max(ans,up[i][j]+le[i][j]+down[i][j]+ri[i][j]);
		}
	}
	printf("%d\n",max(ans-3,0));//注意降落点多访问了三次,ans也可能为0,这样结果为0 
}
int main()
{
	cin>>T;
	while(T--)
	{
		read();
		solve();
	}
	return 0;
}

记忆化搜索代码

#include <cstdio>
#include <algorithm>
#include <cstring>
typedef long long LL;
using namespace std;
const int maxn=1e3+50;

char mp[maxn][maxn];
int a[maxn][maxn][4][4], nex[4][2]={-1,0,0,1,1,0,0,-1};
int n,m;
//搜索 
int dfs(int x,int y,int t,int c){
    //printf("(%d %d %d\n",x,y,t);
    if(1<=x&&x<=n && 1<=y&&y<=m){
         if(mp[x][y]=='0') return 0;
         //在一个方向上,一个点只会向两个方向进行延伸 
         if(a[x][y][t][c]) return a[x][y][t][c];//剪枝 
         int nt;
         //注意这里的处理 
         if(t==c) nt = (t+1)%4;
         else     nt = c;
         return a[x][y][t][c] = dfs(x+nex[nt][0], y+nex[nt][1], nt, c) + 1;
    }
    else return 0;
} 

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        memset(a,0,sizeof(a));
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++){
            scanf("%s",mp[i]+1);
        }
        int ans=0;
        //printf("--------\n");
        for(int i=1; i<=n; i++){
            for(int j=1; j<=m; j++){

                if(mp[i][j]=='1'){
                    int tmp=1;
                    for(int k=0; k<4; k++){
                        tmp += dfs(i+nex[k][0], j+nex[k][1], k, k);
                        //printf("--%d\n",dfs(i+nex[k][0], j+nex[k][1], k, k));
                    }
                    ans = max(ans, tmp);
                }
            }
        }
        printf("%d\n",ans);
    }
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值