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 << ‘\t‘;
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 }

原文地址:https://www.cnblogs.com/bianjunting/p/10599390.html

时间: 2024-10-09 19:55:28

NYOJ_矩形嵌套(DAG上的最长路 + 经典dp)的相关文章

POJ 1949 Chores(DAG上的最长路 , DP)

题意: 给定n项任务, 每项任务的完成用时t和完成每项任务前需要的k项任务, 求把所有任务完成的最短时间,有当前时间多项任务都可完成, 那么可以同时进行. 分析: 这题关键就是每项任务都会有先决条件, 要完成该项任务a必须先完成他的先决条件. 所以对于每个先决条件, 我们构建一条有向边到任务本身, 然后因为要求一个最小值, 按照最长路的方式松弛(dis[v] >= dis[u] + d, u是v的先决条件, d是v的完成时间,我们以边的终点完成时间作为边的权), 遇到没有出度的边记录答案. 方法

HDU 3249 Test for job (有向无环图上的最长路,DP)

 解题思路: 求有向无环图上的最长路,简单的动态规划 #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #define LL long long using namespace std; const int

NYOJ 16 矩形嵌套 (DAG上的DP)

矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中.你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内. 输入 第一行是一个正正数N(0<N<10),表示测试数据组数, 每组

uva103(最长递增序列,dag上的最长路)

题目的意思是给定k个盒子,每个盒子的维度有n dimension 问最多有多少个盒子能够依次嵌套 但是这个嵌套的规则有点特殊,两个盒子,D = (d1,d2,...dn) ,E = (e1,e2...en) 只要盒子D的任意全排列,小于盒子E,那么就说明 盒子D能放入盒子E中,其实就是将两个盒子的维度排序,如果前一个盒子的维度依次小于后一个盒子,那么就说明前一个盒子能放入后一个盒子中 这个题目能够转化为最长递增子序列. 首先将盒子的维度从小到大排序,然后将k个盒子,按照排序后的第一维度从小到大排

hdu 1224(动态规划 DAG上的最长路)

Free DIY Tour Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5815    Accepted Submission(s): 1855 Problem Description Weiwei is a software engineer of ShiningSoft. He has just excellently fulfi

[POJ3249]Test for Job [拓扑排序+DAG上的最长路径]

给定一张带点权的DAG 求一条入度为0节点到出度为0节点的最长路 把点权转化为边权(同时多源转化成单源):边u->v的权值为W[v],这样入度为0的节点权值会被遗漏,新开一个点0向入度为0的点u连有向边,权值为W[u],这样就只有0是入度为0的点了. 先进行拓扑排序,再利用DAG拓扑排序后的特性求出最长路径 1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include &l

POJ 3592--Instantaneous Transference【SCC缩点新建图 &amp;&amp; SPFA求最长路 &amp;&amp; 经典】

Instantaneous Transference Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6177   Accepted: 1383 Description It was long ago when we played the game Red Alert. There is a magic function for the game objects which is called instantaneous

HihoCoder1050 树中的最长路 树形DP第三题(找不到对象)

题意:求出的树中距离最远的两个结点之间相隔的距离. 水题一道,以前只会用路的直径来解. 代码如下: #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<memory> #include<algorithm> using namespace std; const int maxn=200010; int dis[maxn],La

嵌套矩形——DAG上的动态规划

有向无环图(DAG,Directed Acyclic Graph)上的动态规划是学习动态规划的基础.很多问题都可以转化为DAG上的最长路.最短路或路径计数问题. 题目描述: 有n个矩形,每个矩形可以用两个整数a,b描述,表示它的长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d,或者b<c,a<d(相当于把矩形X旋转90°).例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)内.你的任务是选出尽可能多的矩形排成一行.使得除了最后一个之外,每个矩形都