【dp | 记忆化搜索】矩形嵌套

DAG上的动态规划

例题:矩阵嵌套   题目链接


【题意】:

只能两种摆法的矩阵,两个矩阵是否能嵌套关键在于:x,y为矩阵的长和宽。

那么嵌套的条件为:x<t.x&&y<t.y   ||   y<t.x && x <t.y

相当于重载这个结构体的 “小于号”


问题可以转化为:

多个矩阵  用小于号连接,找一个最长的情况。

【解法一】:

变相写成LIS,最长上升子序列

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
typedef struct Node {
    int x,y;
    bool operator < (const Node &t) const { //重载小于号
        return (x<t.x&&y<t.y)||(y<t.x&&x<t.y);
    }
}Node;
Node c[N];
bool cmp(Node a,Node b){        //按照矩阵面积排序
    return a.x*a.y < b.x*b.y;
}
int dp[N];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%d%d",&c[i].x,&c[i].y),dp[i]=1;
        sort(c,c+n,cmp);
        int ans=1;
        for(int i=1;i<n;i++){
            for(int j=0;j<i;j++)
                if(c[j]<c[i]&&dp[i]<dp[j]+1)
                    dp[i]=dp[j]+1;
            if(dp[i]>ans)
                ans=dp[i];
        }
        printf("%d\n",ans);
    }
    return 0;
}

【解法二】:写成记忆化搜索:

第一步建图,然后用dfs往下搜索。

写成邻接矩阵的来搜索:

#include<bits/stdc++.h>
using namespace std;
typedef struct Node {
    int x,y;
    bool operator < (const Node &t) const {
        return (x<t.x&&y<t.y) || (y<t.x && x<t.y);
    }
}Node ;
const int N=1e3+10;
int G[N][N],n,dp[N],ans;
Node a[N];
int dfs(int x){
    if(dp[x]) return dp[x];
    int tmp=1;
    for(int i=1;i<=n;i++)
        if(G[x][i])
            tmp=max(dfs(i)+1,tmp);
    return dp[x]=tmp;
}
int main()
{
    int T;
    for(scanf("%d",&T);T;T--){
        ans=0;
        memset(G,0,sizeof(G));
        memset(dp,0,sizeof(dp));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if( a[i]<a[j] )
                    G[i][j]=1;
        for(int i=1;i<=n;i++)
            ans=max(ans,dfs(i));
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/88060806