BZOJ 3208 花神的秒题计划Ⅰ 记忆化搜索

题目大意:给定一个矩阵,多次改变某个点的权值,设定某个子矩阵内的所有点可用/禁用,求滑雪的最大长度

再也不敢不看数据范围就做题了233333

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 710
using namespace std;
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
int n,m,a[M][M],f[M][M];
bool reserved[M][M];
int Memorial_Search(int x,int y)
{
	if(reserved[x][y])
		return 0;
	if(f[x][y])
		return f[x][y];
	int i;
	f[x][y]=1;
	for(i=0;i<4;i++)
	{
		int xx=x+dx[i];
		int yy=y+dy[i];
		if(xx<=0||yy<=0||xx>n||yy>n)
			continue;
		if(a[xx][yy]>=a[x][y])
			continue;
		f[x][y]=max(f[x][y],Memorial_Search(xx,yy)+1);
	}
	return f[x][y];
}
int main()
{
	int i,j,k,x1,y1,x2,y2,x,y,z;
	char p[10];
	cin>>n;
	for(i=1;i<=n;i++)
		for(j=1;j<=n;j++)
			scanf("%d",&a[i][j]);
	cin>>m;
	for(k=1;k<=m;k++)
	{
		scanf("%s",p);
		switch(p[0])
		{
			case 'C':
				scanf("%d%d%d",&x,&y,&z);
				a[x][y]=z;
				break;
			case 'S':
				scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
				for(i=x1;i<=x2;i++)
					for(j=y1;j<=y2;j++)
						reserved[i][j]=1;
				break;
			case 'B':
				scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
				for(i=x1;i<=x2;i++)
					for(j=y1;j<=y2;j++)
						reserved[i][j]=0;
				break;
			case 'Q':
				int ans=0;
				memset(f,0,sizeof f);
				for(i=1;i<=n;i++)
					for(j=1;j<=n;j++)
						ans=max(ans,Memorial_Search(i,j) );
				printf("%d\n",ans);
				break;
		}
	}
}


你可能感兴趣的:(记忆化搜索,bzoj,BZOJ3208)