解题思路:考虑到动态规划无后效性的特点,必须先从较低点算至较高点。利用优先队列(或排好序的队列)依次去处理各个高度。
动态转换方程:f[i][j]=max(f[i-1][j],f[i][j+1],f[i+1][j],f[i][j-1])+1
#include <stdio.h>
typedef struct { //用以保存各个高度的信息
int now;
int i;
int j;
}box;
int max(int a,int b) {
return a>b?a:b;
}
int pari(box a[],int l,int r) {
int i=l,j=r;
box tem=a[i];
while(i<j) {
while(i<j&&a[j].now>=tem.now)j--;
a[i]=a[j];
while(i<j&&a[i].now<=tem.now)i++;
a[j]=a[i];
}
a[j]=tem;
return i;
}
void quk(box a[],int l,int r) { //快速排序
int q;
if(l<r) {
q=pari(a,l,r);
quk(a,l,q-1);
quk(a,q+1,r);
}
}
int main() {
int R,C,i,j,t=0,k=0,now,maxn=0;
scanf("%d%d",&R,&C);
int f[102][102];
box a[R*C];
int gri[102][102];
for(i=1;i<=R;i++)
for(j=1;j<=C;j++) {
scanf("%d",&gri[i][j]);
a[t].now=gri[i][j];
a[t].i=i;
a[t].j=j;
f[i][j]=1;
t++;
}
quk(a,0,t-1); //将各个高度从小到大排列
while(k<t) { //从小到大依次处理各个高度
i=a[k].i;
j=a[k].j;
now=a[k].now;
k++;
if(gri[i-1][j]<now) f[i][j]=max(f[i][j],f[i-1][j]+1);
if(gri[i+1][j]<now) f[i][j]=max(f[i][j],f[i+1][j]+1);
if(gri[i][j-1]<now) f[i][j]=max(f[i][j],f[i][j-1]+1);
if(gri[i][j+1]<now) f[i][j]=max(f[i][j],f[i][j+1]+1);
if(maxn<f[i][j]) maxn=f[i][j]; //取最大路径和
}
printf("%d",maxn);
return 0;
}
洛谷80分算法,不知道哪里有问题。