zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    codeforces 589G G. Hiring(树状数组+二分)
    树状数组的小总结
    virtualenv
    Redis备份与恢复
    Linux 网站相关
    MySQL文章参考
    动态执行表不可访问,本会话的自动统计被禁止 。 在执行菜单里你可以禁止统计,或在v$session,v$sesstat 和 v$statname 表里获得select权限
    app已损坏,打不开。你应该将它移到废纸篓
    macos系统用virtualbox安装Linux系统无法设
    Hadoop 分布式部署HDFS-hadoop用户部署
  • 原文地址:https://www.cnblogs.com/bianjunting/p/10599390.html
Copyright © 2011-2022 走看看