CJOJ 1070 【Uva】嵌套矩形(动态规划 图论)

Description

有 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) 内。

你的任务是选出尽量多的矩形,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。

Input

第一行一个正整数 n (n <= 1000)。

接下来 n 行每行两个正整数 a, b 表示矩形 i 的长和宽。

Output

第一行一个整数 k 表示符合条件的最多矩形数。

第二行 k 个整数依次表示符合条件矩形的编号,要求字典序最小。

Sample Input

8

14 9

15 19

18 12

9 10

19 17

15 9

2 13

13 10

Sample Output

4

4 8 3 2

Http

CJOJ:http://oj.changjun.com.cn/problem/detail/pid/1070

Source

动态规划,图论

解决思路

这道题可以转化成图论问题。若有正方形A可以嵌套在正方形B中,我们就连一条边A->B,呢么这道题就转化成为求DAG(为什么是DAG呢,因为一个矩形不可能经过若干次嵌套后嵌套在自己里面,所以一定不会有环)上从任意一点出发的最长路径

我们令F[i]表示从i出发的最长路径,那么对于所有存在的路径i->j,一定有F[i]=max(F[j]+1)。由于初始起点不好计算(其实也可以计算,如用拓扑排序),为了方便期间,我们用记忆化搜索来实现。

为什么不令F[i]表示到i的最长路径呢?这样做虽然没错,但是最终输出路径时的解不一定是字典序(除非还用一个数组记录路径),因为在这里我们是用的从动归转移方程倒推路径。

,我们知道F[i]一定是从其能连到的一个点(假设是j)得到的,那么我们从1到n枚举,看是否满足F[i]=F[j]+1。因为我们是从小到大枚举的,又是正序输出,所以可以保证字典序。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std; const int maxN=2000;
const int inf=2147483647; int n;
int A[maxN];
int B[maxN];
int G[maxN][maxN];//用邻接矩阵存边
int F[maxN];//从i出发的最长路,F[i]为-1时表示还未访问 int dfs(int x);
void outp(int ans); int main()
{
memset(F,-1,sizeof(F));
memset(G,-1,sizeof(G));
cin>>n;
for (int i=1;i<=n;i++)
{
cin>>A[i]>>B[i];
if (A[i]<B[i])
swap(A[i],B[i]);
}
for (int i=1;i<=n;i++)//判断两个矩形是否满足嵌套关系
for (int j=1;j<=n;j++)
if (((A[i]<A[j])&&(B[i]<B[j]))||((A[i]<B[j])&&(B[i]<A[j])))
G[i][j]=1;
for (int i=1;i<=n;i++)
if (F[i]==-1)
F[i]=dfs(i);
/*cout<<"FFF"<<endl;
for (int i=1;i<=n;i++)
cout<<F[i]<<' ';
cout<<endl;*/
int Ans=0;
for (int i=1;i<=n;i++)
if (F[i]>F[Ans])
Ans=i;//找出最大值
cout<<F[Ans]<<endl;
outp(Ans);//倒推出方案
cout<<endl;
return 0;
} int dfs(int x)//记忆化搜索
{
if (F[x]!=-1)//说明F[x]已经计算过了,直接返回
return F[x];
F[x]=1;
for (int i=1;i<=n;i++)
if (G[x][i]==1)//求出F[x]的最大值
F[x]=max(F[x],dfs(i)+1);
return F[x];
} void outp(int ans)//倒推出解,但要注意是正序输出(因为我们定义的F[i]表示的是从i出发的最短路,所以推的时候是顺着最短路推的)
{
cout<<ans<<' ';
for (int i=1;i<=n;i++)
if ((G[ans][i]==1)&&(F[ans]==F[i]+1))
{
outp(i);
return;
}
return;
}

CJOJ 1070 【Uva】嵌套矩形(动态规划 图论)的更多相关文章

  1. DAG上的动态规划之嵌套矩形

    题意描述:有n个矩形,每个矩形可以用两个整数a.b描述,表示它的长和宽, 矩形(a,b)可以嵌套在矩形(c,d)当且仅当a<c且b<d, 要求选出尽量多的矩形排成一排,使得除了最后一个外, ...

  2. DAG上的动态规划---嵌套矩形(模板题)

    一.DAG的介绍 Directed Acyclic Graph,简称DAG,即有向无环图,有向说明有方向,无环表示不能直接或间接的指向自己. 摘录:有向无环图的动态规划是学习动态规划的基础,很多问题都 ...

  3. HDOJ-1069(动态规划+排序+嵌套矩形问题)

    Monkey and Banana HDOJ-1069 这里实际是嵌套矩形问题的变式,也就是求不固定起点的最长路径 动态转移方程为:dp[i]=max(dp[j]+block[i].h|(i,j)∈m ...

  4. CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu?

    CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu? Description (原题来自刘汝佳<训练指南>Pa ...

  5. NYOJ16|嵌套矩形|DP|DAG模型|记忆化搜索

    矩形嵌套 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a& ...

  6. P1375 嵌套矩形

    题目Problem 嵌套矩形 Time Limit: 1000ms    Memory Limit: 131072KB 描述Descript. 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形 ...

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

    有向无环图(DAG,Directed Acyclic Graph)上的动态规划是学习动态规划的基础.非常多问题都能够转化为DAG上的最长路.最短路或路径计数问题. 题目描写叙述: 有n个矩形,每一个矩 ...

  8. oj.1677矩形嵌套,动态规划 ,贪心

    #include<iostream> #include<algorithm> #include<cstring> using namespace std; stru ...

  9. [ACM_动态规划] 嵌套矩形

    问题描述:有n个矩阵,每个矩阵可以用两个整数a,b来表示 ,表示他的长和宽,矩阵X (a,b) 可以 嵌套 到Y (c,d) 里面当且仅当 a < c &&  b < d  ...

随机推荐

  1. .net Core1.0 邮件发送

    今天一天早,公司需要将之前的.net Core项目增加一个预处理机制,就是当程序出现异常后给我们的开发人员发送邮件,因为今天写些关于.netCore上发送邮件. 根据查阅资料发现在目前的Core1.0 ...

  2. Linux常用命令说明(记录自己Linux命令使用情况,后续会持续更新)

    首次记录时间--20170602 感觉自己Linux命令使用掌握的情况非常差,今天先记录当前会的几个. 1#cd(change directory) 切换工作目录(或者叫修改当前目录) eg. cd ...

  3. 前端向后台的华丽转身 — PHP入门篇

    三个月就这么悄悄溜走了,本K对于前端虽然有了一定的认识,但对一些方面还是处于一种比较萌币的状态,就在这种萌币状态下,本K又跟着大神浩开始了后台语言-PHP语言的学习.PHP的学习对于学过其他语言的人来 ...

  4. Linux笔记③(ftp、nfs、ssh服务器搭建)

    1.ftp服务器搭建(利用vsftpd这个工具) 作用:文件的上传和下载 服务器端: 修改配置文件,配置文件目录:/etc/vsftpd.conf ,修改里面的允许匿名访问.指定匿名访问目录等操作,根 ...

  5. 【小练习06】HTML+CSS--电影公告

    要求实现如下效果图: 代码演示 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"&g ...

  6. python之numpy库[1]

    python-numpy python中的数据 一维数据 用列表和集合表示 数组与列表的关系 列表:数据类型可以不同 数组:数据类型可以相同 多维数据 用列表表示 高维数据 用字典表示 高维数据仅利用 ...

  7. 面向面试编程——javascript对象的几种创建方式

    javascript对象的几种创建方式 总共有以下几个模式: 1.工厂模式 2.构造函数模式 3.原型模式 4.混合构造函数和原型模式 5.动态原型模式 6.寄生构造函数模式 7.稳妥构造函数模式 1 ...

  8. .NET和JAVA 反射对比

    反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等程序集内部的信息.使用反射可以看到一个程序集内部的接口.类.方法.字段.属性.特性等等信息.在System.Reflectio ...

  9. 转 使用HAProxy,PHPRedis,和MySQL支撑10亿请求每周架构细节

    [编者按]在公司的发展中,保证服务器的可扩展性对于扩大企业的市场需要具有重要作用,因此,这对架构师提出了一定的要求.Octivi联合创始人兼软件架构师Antoni Orfin将向你介绍一个非常简单的架 ...

  10. java 实例变量的初始化

    1.对于实例变量,该类没创建一次实例,就需要为实例变量分配一块内存空间:2.程序通过Person对象来访问eyeNum类变量时,底层依然会转换为通过Person访问eyeNum类变量:3.当Perso ...