zoukankan      html  css  js  c++  java
  • [ACM_动态规划] 嵌套矩形

    问题描述:有n个矩阵,每个矩阵可以用两个整数a,b来表示 ,表示他的长和宽,矩阵X (a,b) 可以 嵌套 到Y (c,d) 里面当且仅当 a < c &&  b < d  ||  a < d && b < c . 选出最多这种矩阵。先输出最多的数量,在输出最小字典序路径。
    问题分析:本题是DAG(有向无环图)最长路问题,设d[i]为以i结尾的最长链的长度,则状态转移方程为:d[i]=max{0,d[j]|矩形j可以嵌套在矩形i中}+1 ;这里用map[i][j]存储i可嵌入j中
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 1000+5
    
    class Rect{
    public:
        int length;
        int width;
    };
    bool ok(Rect& a,Rect& b){          //嵌套关系判定函数
        return (a.length<b.length && a.width<b.width)
                ||(a.length<b.width && a.width<b.length);
    }
    
    
    int d[maxn],n,map[maxn][maxn];    //d[]用来存储以i结尾的最大长度,map[i][j]表示i可嵌套在j中
    Rect rect[maxn];
    
    int dfs(int cur)                  //深搜,记忆化搜索
    {
        if( d[cur] > 0) return d[cur];//已经找过的直接输出
        d[cur] = 1;                   //没找的先付初值1,然后深搜寻找
        for(int i=1;i<=n;i++)
        {
            if( map[cur][i] && d[cur] < dfs(i)+1)
            {
                d[cur] = dfs(i)+1;
            }
        }
        return d[cur];
    }
    void out(int i)                   //反向追踪找到选取图形的标号
    {
        cout << i << " ";
        for(int j=1;j<=n;j++)
        {
            if( map[i][j] && d[i] == d[j]+1)
            {
                out(j);
                break;
            }
        }
    }
    
    int main(){
        
        for(;cin>>n && n;){
    
            int i,j;
            
            for(i=1;i<=n;i++){                           //输入
                cin>>rect[i].length>>rect[i].width;
            }
    
            memset(map,0,sizeof(map));                   //构造一个嵌套关系的邻接矩阵
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                    if(ok(rect[i],rect[j]))
                        map[i][j]=1;
    
            memset(d,0,sizeof(d));                       //深搜记忆化完成d[]表
            for(i=1;i<=n;i++){
                dfs(i);
            }
    
    
            int max=0,ds;                                //找出d[]的最大值并用ds存储尾链位置
            for(i=1;i<=n;i++){
                if(max<d[i]){
                    max=d[i];
                    ds=i;
                }
            }
    
            cout<<max<<'
    ';
            out(ds);cout<<'
    ';
        }
    }
    
                
    
    
            
    View Code
  • 相关阅读:
    Linux
    前端
    第一章 初识 MyBatis
    mysql 复习
    五 、 Kafka producer 拦截器(interceptor) 和 六 、Kafka Streaming案例
    spark graphx图计算
    四、Kafka API 实战
    三、Kafka工作流程分析
    二、Kafka集群部署
    一、KafKa概述
  • 原文地址:https://www.cnblogs.com/zjutlitao/p/3219253.html
Copyright © 2011-2022 走看看