链接:https://vjudge.net/problem/POJ-1088
题意:给你n,m,再给一个n*m的矩阵(h[n][m])。可以往相邻的四个位置走,前提是当前h要大于下一个位置的h,求最长的长度。也就是求最长严格下降子序列的长度。
思路:贪心的思想,肯定是高度大的更新高度小的。用一个优先队列就好了,把位置全放入队列,大的先出队列,并更新可到达的位置。
状态:dp[i][j]:表示以(i,j)位置为终点的最长序列的长度。
PS:想到要从大的往小的更新了,没想到用优先队列。。。。。。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#define ll long long
using namespace std;
const int N = 110;
int dp[N][N],h[N][N];
int nex[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node
{
int x,y,h;
node(){}
node(int x,int y,int h):x(x),y(y),h(h){}
friend bool operator <(const node& a,const node& b)
{
return a.h<b.h;
}
}now;
priority_queue<node> q;
int main(void)
{
int n,m,nx,ny,ans=1;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&h[i][j]);
q.push(node(i,j,h[i][j]));
dp[i][j]=1;
}
while(!q.empty())
{
now=q.top();
q.pop();
for(int i=0;i<4;i++)
{
nx=now.x+nex[i][0];
ny=now.y+nex[i][1];
if(nx<1||nx>n||ny<1||ny>m) continue;
if(h[nx][ny]<now.h)
dp[nx][ny]=max(dp[nx][ny],dp[now.x][now.y]+1);
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(ans<dp[i][j])
ans=dp[i][j];
printf("%d\n",ans);
return 0;
}