這題的思路就是遍歷所有格子,如果這個格子的周圍有比他小的,那麼她的最大長度就是周圍最大的長度+1和自己比較,取較大的,但是要進行深搜,因爲後面沒有遍歷到的格子他的最大長度還不知道呢,需要記憶化搜索,也就是要把最大長度保存起來,否則會超時哦!
#include <algorithm>
using namespace std;
int r,c;
int num[101][101];//保存每個格子的數
int best[101][101];//保存最大長度
int dx[4]={-1,0,0,1};//這兩個數組用來移動至上下左右
int dy[4]={0,1,-1,0};
int dp(int a,int b)
{
if(best[a][b]>1)return best[a][b];//如果以前已經計算過了就直接返回那個值
for(int k=0;k<4;k++)
if(a+dx[k]>=1&&a+dx[k]<=r&&b+dy[k]>=1&&b+dy[k]<=c&&num[a+dx[k]][b+dy[k]]<num[a][b])//如果在範圍內,並且數字比自己小的話
best[a][b]=max(best[a][b],dp(a+dx[k],b+dy[k])+1);//周圍最大的長度+1和自己比較,取較大的,這裏用了函數dp,實際上是進行深搜了,這樣才能保證周圍的長度都是正確的
return best[a][b];
}
int main()
{
cin>>r>>c;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
cin>>num[i][j];
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
best[i][j]=1;
int max=0;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(dp(i,j)>max)
max=dp(i,j);
cout<<max<<endl;
}
http://mhxyzhengcheng.blog.163.com/blog/static/121764471201015114616288/
轉自:http://mhxyzhengcheng.blog.163.com/blog/static/121764471201015114616288/
PKU 1088 滑雪 —— DFS暴力能也能達到150ms,常規DP或記憶化搜索都能0ms. 我是用常規的DP,先用sort,然後按高度遞推,具體見程序。
程序清單:
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100
const int move[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int h[MAXN][MAXN],lp[MAXN][MAXN];
struct s
{
int x,y,h;
}a[MAXN*MAXN];
bool cmp(s a,s b)
{
return a.h<b.h;
}
int main()
{
int i,j,k,r,c,x,y,ans;
for (k=i=0,scanf("%d%d",&r,&c);i<r;++i)
for (j=0;j<c;++j)
{
scanf("%d",&h[i][j]);
a[k].x=i;
a[k].y=j;
a[k++].h=h[i][j];
}
sort(a,a+k,cmp);
memset(lp,0,i*j*4);
ans=0;
for (i=0;i<k;++i)
{
for (j=0;j<4;++j)
{
x=a[i].x+move[j][0];
y=a[i].y+move[j][1];
if (x>=0&&x<r&&y>=0&&y<c&&h[x][y]<a[i].h&&lp[a[i].x][a[i].y]<=lp[x][y])
lp[a[i].x][a[i].y]=lp[x][y]+1;
}
if (ans<=lp[a[i].x][a[i].y])
ans=lp[a[i].x][a[i].y];
}
printf("%d/n",ans+1);
return 0;
}
轉自: http://hi.baidu.com/wuxyy/blog/item/876f5143778efa109313c6b1.html