【洛谷P1434】滑雪

来源:互联网 发布:电脑打字用什么软件 编辑:程序博客网 时间:2024/06/06 07:18

题意:找一个二维的最长上升子序列
题解:
1.贪心
对每个点的高度进行排序,然后再DP,这样就可以保证在转移的时候,上一个状态一定已经被计算出来(好像会wa)

#include<cstdio>#include<iostream>#include<algorithm>#define maxn 105using namespace std;struct node{    int x,y,v;}b[maxn*maxn];int a[maxn][maxn],f[maxn][maxn]={0},N,M,ecnt=0;int dx[4]={-1,0,1,0};int dy[4]={0,1,0,-1};int cmp(node a,node b){    if(a.v!=b.v) return b.v>a.v;    if(a.x!=b.v) return b.x>a.x;    return b.y>a.y;}int main(){    int ans=0;    cin>>N>>M;    for(int i=0;i<N;i++)        for(int j=0;j<M;j++)        {            cin>>a[i][j];            b[ecnt].x=i, b[ecnt].y=j, b[ecnt++].v=a[i][j];        }    sort(b,b+ecnt,cmp);    for(int i=0;i<ecnt;i++)        for(int j=0;j<4;j++)        {            int nx=b[i].x+dx[j], ny=b[i].y+dy[j];            if(nx>=0&&ny>=0&&nx<N&&ny<M && b[i].v>a[nx][ny])                f[b[i].x][b[i].y]=max(f[nx][ny]+1,f[b[i].x][b[i].y]);        }    for(int i=0;i<N;i++)        for(int j=0;j<M;j++)            ans=max(ans,f[i][j]);    ans++;            cout<<ans<<endl;    return 0;}

2.记忆化搜索
对每一个点DFS,如果这个点的DP值已经算出来了,那么直接返回这个值,如果没有算出来,那么DFS它上下左右四个点

#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>using namespace std;const int dx[4]={-1,0,1,0};const int dy[4]={0,1,0,-1};int m[101][101],f[101][101];int r,c; int search(int x,int y){    int tot=1;    if(f[x][y]) return f[x][y];    for(int i=0;i<4;i++)    {        int nx=x+dx[i];        int ny=y+dy[i];        if(nx>=1&&nx<=r&&ny>=1&&ny<=c&&m[x][y]<m[nx][ny])        {            int tmp=search(nx,ny)+1;            tot=max(tmp,tot);        }    }    return tot;}int main(){    memset(m,0xaf,sizeof(m));    scanf("%d%d",&r,&c);    for (int i=1;i<=r;i++)        for (int j=1;j<=c;j++)            scanf("%d",&m[i][j]);    int ans=0;    for (int i=1;i<=r;i++)        for (int j=1;j<=c;j++)        {            f[i][j]=search(i,j);            ans=max(ans,f[i][j]);        }    printf("%d\n",ans);    return 0;}
原创粉丝点击