POJ1088 滑雪 记忆化搜索

事实证明即使是水题也不能乱写暴力= =

以为暴力加点剪枝就能过了嘛,然后就怒写暴力= =

前车之鉴:

Problem: 1088		User: BPM136
Memory: N/A		Time: N/A
Language: G++		Result: Time Limit Exceeded

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
	LL d=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
	return d*f;
}
#define N 105
#define MAX 1000000000
int a[N][N];
int f[N][N];
int n,m,ans=1;
int pre[4][2];

void getpre()
{
	int cnt=0;
	fo(i,-1,1)
	fo(j,-1,1)
	if(abs(i-j)==1)
	{
		pre[cnt][0]=i;pre[cnt++][1]=j;
	}
}

//int v[N][N];
void dfs(int x,int y,int val,int anss)
{
	if(x<1||y<1||x>n||y>m)return;
//	if(v[x][y]==1)return;
	if(a[x][y]>=val||f[x][y]>anss)return;
	int cost=anss+1;ans=max(ans,cost);
	f[x][y]=max(f[x][y],anss);//v[x][y]=1;
	fo(i,0,3)
	dfs(x+pre[i][0],y+pre[i][1],a[x][y],cost);
//	v[x][y]=0;
}

int main()
{
	getpre();
	n=read(),m=read();
	fo(i,1,n)
	{
		fo(j,1,m)
		a[i][j]=read();
	}
	fo(i,1,n)
	{
		fo(j,1,m)
		{
//			memset(v,0,sizeof(v));
			dfs(i,j,MAX,0);
		}
	}
	cout<<ans<<endl;
	return 0;
}
然后我T了几次后决定还是写个规范点的记忆化搜索= =

Problem: 1088		User: BPM136
Memory: 804K		Time: 32MS
Language: G++		Result: Accepted

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
inline LL read()
{
	LL d=0,f=1;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
	return d*f;
}
#define N 105
#define MAX 1000000000
int a[N][N];
int f[N][N];
int n,m,ans=-1;
int pre[4][2];

void getpre()
{
	int cnt=0;
	fo(i,-1,1)
	fo(j,-1,1)
	if(abs(i-j)==1)
	{
		pre[cnt][0]=i;pre[cnt++][1]=j;
	}
}

int dfs(int x,int y)
{
	if(f[x][y])return f[x][y];
	if(ans==n*m)return 0;
	fo(i,0,3)
	{
		int tx=x+pre[i][0],ty=y+pre[i][1];
		if(tx>=1&&tx<=n&&ty>=1&&ty<=m)
		{
			if(a[tx][ty]<a[x][y])
			{
				int ret=dfs(tx,ty);
				f[x][y]=max(f[x][y],ret+1);
			}
		}
	}
	return f[x][y];
}

int main()
{
	getpre();
	scanf("%d%d",&n,&m);
	fo(i,1,n)
	{
		fo(j,1,m)
		scanf("%d",&a[i][j]);
	}
	fo(i,1,n)
	{
		fo(j,1,m)
		{
			int temp=dfs(i,j);
			ans=max(ans,temp);
//			cout<<f[i][j]<<' ';
		}//cout<<endl;
	}
	cout<<ans+1<<endl;
	return 0;
}



你可能感兴趣的:(dp,搜索)