zoukankan      html  css  js  c++  java
  • DAG上的动态规划---嵌套矩形(模板题)

    一、DAG的介绍

    Directed Acyclic Graph,简称DAG,即有向无环图,有向说明有方向,无环表示不能直接或间接的指向自己。

    摘录:有向无环图的动态规划是学习动态规划的基础,很多问题都可以转化为DAG上的最长路、最短路或路径计数问题。

    通常需要建图,不复杂的也可以当最长上升子序列处理,就不必建图,但都包含运用有向无环图的思想。

    二、例题

    有n(1 <= n <= 1000)个矩形,长为a,宽为b。矩形X(a,b)可以嵌套在矩形Y(c,d)中,当且仅当a < c,b < d,或者a < d,b < c。求最大的嵌套数。

    三、解题思路

    矩形X可以嵌套矩形Y,则从X连条边到Y,矩形不能直接或间接的嵌套自己,所以无环。最大的嵌套次数,就是求这个图上的最长路。

    四、代码实现

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdbool>
     5 #include<vector>
     6 #include<algorithm>
     7 using namespace std;
     8 
     9 const int maxn = 1000 + 10;
    10 struct Node
    11 {
    12     int x, y;
    13     Node(int x, int y) :x(x), y(y) {}
    14     Node() {}
    15     bool operator < (const Node &n)const {
    16         return (x < n.x&& y < n.y) || (x < n.y&& y < n.x);
    17     }
    18 };
    19 vector<Node>vec;
    20 int n;
    21 int d[maxn];    //d[i]表示从节点i出发的最长路的长度
    22 bool G[maxn][maxn];
    23 int cnt = 0;
    24 
    25 //建图
    26 void creatGraph()
    27 {
    28     for (int i = 0; i < n; i++)
    29         for (int j = 0; j < n; j++)
    30         {
    31             if (vec[i] < vec[j])  G[i][j] = true;
    32         }
    33 }
    34 
    35 //计算从i出发的最长路径
    36 int dp(int i)
    37 {
    38     int& ans = d[i];
    39     if (ans > 0)  return ans;
    40     ans = 1;
    41     for (int j = 0; j < n; j++)
    42         if (G[i][j])  ans = max(ans, dp(j) + 1);
    43     return ans;
    44 }
    45 
    46 //解决问题
    47 void slove()
    48 {
    49     creatGraph();
    50     int res = 0;
    51     for (int i = 0; i < n; i++)
    52         res = max(res, dp(i));            //整体的时间复杂度为O(n^2)
    53 
    54     printf("Case %d: maximum  = %d
    ", ++cnt, res);
    55 }
    56 int main()
    57 {
    58     while (scanf("%d", &n) == 1 && n)
    59     {
    60         vec.clear();
    61         memset(d, 0, sizeof(d));
    62         memset(G, false, sizeof(G));
    63         int x, y;
    64         for (int i = 0; i < n; i++)
    65         {
    66             scanf("%d%d", &x, &y);
    67             vec.push_back(Node(x, y));
    68         }
    69         slove();
    70     }
    71 }

     当然,这题也可以用最长上升子序列做,可以参考我的前一篇博客。

  • 相关阅读:
    NLog.Config的配置示例
    极限定义新讲:动态定义与静态定义
    rclone命令
    linux用户管理命令
    vim常用命令
    Python解二元二次方程组
    英雄联盟为什么这么难玩?——认识所有英雄
    snap安装、运行ss
    阿里云邮件推送服务Python API发送邮件
    Visual Studio #include<bits/stdc++.h>万能头文件
  • 原文地址:https://www.cnblogs.com/lfri/p/9444356.html
Copyright © 2011-2022 走看看