• NYOJ_矩形嵌套(DAG上的最长路 + 经典dp)


      本题大意:给定多个矩形的长和宽,让你判断最多能有几个矩形可以嵌套在一起,嵌套的条件为长和宽分别都小于另一个矩形的长和宽。

      本题思路:其实这道题和之前做过的一道模版题数字三角形很相似,大体思路都一致,这道题是很经典的DAG上的最长路问题,用dp[ i ]表示以i为出发点的最长路的长度,因为每一步都只能走向他的相邻点,则

    d[ i ]  = max(d[ j ] + 1)这里 j 是任意一个面积比 i 小的举行的编号。

      下面的代码中附带了最小字典序最长路打印的问题,我们找到第一个路径最长的 i,往后每次都找第一个符合条件的 i 输出即可。

      参考代码:

     1 #include <iostream>
     2 #include <cstring>
     3 using namespace std;
     4 
     5 typedef pair<int ,int > P;
     6 int n, m;
     7 const int maxn = 100 + 5, Max = 1000 + 5;
     8 int G[maxn][maxn], cnt, b;
     9 int d[maxn];
    10 P rectangle[Max];
    11 
    12 bool check(int i, int j) {
    13     return (rectangle[i].first > rectangle[j].first && rectangle[i].second > rectangle[j].second) || 
    14         (rectangle[i].first > rectangle[j].second && rectangle[i].second > rectangle[j].first);
    15 }
    16 
    17 int dp(int i) {
    18     int &ans = d[i];
    19     if(ans != -1) return ans;
    20     ans = 1;
    21     for(int j = 0; j < maxn; j ++)
    22         if(G[i][j] == 1) ans = max(ans, dp(j) + 1);
    23     cnt = max(cnt, ans);
    24     return ans;
    25 }
    26 
    27 void print_ans(int i) {
    28     cout << i << '	';
    29     for(int j = 0; j < maxn; j ++)
    30         if(G[i][j] == 1 && d[i] == d[j] + 1) {
    31             print_ans(j);
    32             break;
    33         }
    34 }
    35 
    36 int main () {
    37     int n;
    38     cin >> n;
    39     while(n --) {
    40         cnt = 0;
    41         memset(d, -1, sizeof d);
    42         memset(G, -1, sizeof G);
    43         cin >> m;
    44         for(int i = 0; i < m; i ++)
    45             cin >> rectangle[i].first >> rectangle[i].second;
    46         for(int i = 0; i < m; i ++)
    47             for(int j = 0; j < m; j ++)
    48                 if(check(i, j))
    49                     G[i][j] = 1;
    50         for(int i = 0; i < m; i ++)
    51             dp(i);
    52         cout << cnt << endl;
    53         for(int i = 0; i < maxn; i ++) if(d[i] == cnt) b = i;
    54         // print_ans(b);
    55     }
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    [SDOI2015] 序列统计
    [BZOJ3514] Codechef MARCH14 GERALD07加强版
    [CF1082E] Increasing Frequency
    [CF1093G] Multidimensional Queries
    [HNOI2013] 切糕
    [HEOI2017] 寿司餐厅 + 最大权闭合子图的总结
    [BZOJ3771] Triple
    [HEOI2016] 字符串
    [总结] 后缀数组学习笔记
    [Luogu 3613] 睡觉困难综合征
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10599390.html
Copyright © 2020-2023  润新知