您的位置:首页 > 其它

pku1088:滑雪

2012-07-25 00:24 357 查看
pku1088:求矩阵的最长降序路线: http://poj.org/problem?id=1088
解法1:dp+dfs记忆性搜索:dp[x][y]=max(dp[i][j]+1)((i,j)为(x,y)的上下左右点),所以要先算i,j的最优值,所以需要用到递归
code1:


#include<iostream>
#include<cstdio>
#include<cstdlib>
int v[150][150],ans[150][150],n,m;
int dx[]={0,0,-1,1};
int dy[]={-1,1,0,0};
int dp(int a,int b)
{
if(ans[a][b]>0)return ans[a][b];       //若已算过,直接返回,不然会超时
for(int i=0;i<4;i++)
{
if(a+dx[i]>=0&&a+dx[i]<n&&b+dy[i]>=0&&b+dy[i]<m&&v[a][b]>v[a+dx[i]][b+dy[i]])
{
if(ans[a][b]<dp(a+dx[i],b+dy[i])+1)
ans[a][b]=dp(a+dx[i],b+dy[i])+1;
}
}
return ans[a][b];
}
int main()
{
int max;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&v[i][j]);
}
}
memset(ans,0,sizeof(ans));
max=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(max<dp(i,j))    //求出最大值
max=dp(i,j);
}
}
printf("%d\n",max+1);
}
}


解法2:队列bfs:先把所有点从大到小排序,由于只有大的点才会更新小的点,所以把这些点从大到小放进队列,但比较小的数被大的数更新后,会在后面出队,更新再小的数,这样的话状态数为n*n
code2:


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
int v[150][150],w[150*150],dp[150][150],r[150*150];
struct abc
{
int x,y;
}q[150*150];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
int cmp(int a,int b)
{
return w[a]>w[b];
}
int main()
{
int n,m,max,a,b,xx,yy;
while(scanf("%d%d",&n,&m)!=EOF)
{
int front=0,rear=0,k=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%d",&v[i][j]);
dp[i][j]=1;r[k++]=i*m+j;w[i*m+j]=v[i][j];
}
}
sort(r,r+n*m,cmp);             //排序
for(int i=0;i<n*m;i++)
{
q[rear].x=r[i]/m;q[rear++].y=r[i]%m;
}
max=0;
while(rear>front)
{
a=q[front].x;b=q[front++].y;
for(int k=0;k<4;k++)
{
xx=a+dx[k];yy=b+dy[k];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&v[a][b]>v[xx][yy])
{
if(dp[xx][yy]<dp[a][b]+1)     //(a,b)更新周围四个点的状态
{
dp[xx][yy]=dp[a][b]+1;
if(dp[xx][yy]>max)    //取最大值
max=dp[xx][yy];
}
}
}
}
if(max==0)         //表示所有点都不用更新,如所有点的值都相同
printf("1\n");
else
printf("%d\n",max);
}
}

/*input:
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
output:
25*/


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: