DAG上的DP
引例:NYOJ16
矩形嵌套
- 描述
- 有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),表示测试数据组数,
每组测试数据的第一行是一个正正数n,表示该组测试数据中含有矩形的个数(n<=1000)
随后的n行,每行有两个数a,b(0<a,b<100),表示矩形的长和宽 - 输出
- 每组测试数据都输出一个数,表示最多符合条件的矩形数目,每组输出占一行
- 样例输入
-
1
10
1 2
2 4
5 8
6 10
7 9
3 1
5 8
12 10
9 7
2 2 - 样例输出
-
5 我们可以这样建模:将每个矩形视作一个结点,若矩形A能覆盖矩形B,那么就在作一条结点A指向结点B的有向路径,结果我们会得到一个DAG(有向无环图)。求符合条件的最多矩形数目,就是DAG中最长路径上的结点数目。
求DAG上的最长路径上的结点数目,我们可用记忆化搜索求解,(同poj1088滑雪)
代码如下:#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=;
vector<int> G[MAXN];
int V,E;
int d[MAXN];
int dfs(int u)
{
if(d[u]>) return d[u];
int ans=;
for(int i=;i<G[u].size();i++)
{
ans=max(ans,dfs(G[u][i])+);
}
return d[u]=ans;
}
int main()
{
memset(d,,sizeof(d));
scanf("%d%d",&V,&E);
for(int i=;i<E;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
int ans=;
for(int i=;i<=V;i++)
ans=max(ans,dfs(i));
printf("%d\n",ans+);
return ;
}
/*
7 8
1 2
1 3
3 2
2 4
2 5
4 6
6 5
5 7 7
*/这样 矩形覆盖问题就迎刃而解。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=;
vector<int> G[MAXN];
struct Rect{
int x,y;
}rect[MAXN];
int n;
void createG()
{
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if((rect[i].x<rect[j].x&&rect[i].y<rect[j].y)||(rect[i].y<rect[j].x&&rect[i].x<rect[j].y))
{
G[j].push_back(i);
}
}
int d[MAXN];
int dfs(int u)
{
if(d[u]>) return d[u];
int ans=;
for(int i=;i<G[u].size();i++)
ans=max(ans,dfs(G[u][i])+);
return d[u]=ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++)
{
G[i].clear();
scanf("%d%d",&rect[i].x,&rect[i].y);
}
createG();
memset(d,,sizeof(d));
int ans=;
for(int i=;i<=n;i++)
ans=max(ans,dfs(i));
printf("%d\n",ans+);
} return ;
}该问题也可以转化为最长上升子序列问题求解。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF=;
struct Rect{
int x,y;
}rect[];
int n;
bool comp(const Rect &a,const Rect &b)
{
if(a.x==b.x) return a.y > b.y;//µ±±ß³¤ÏàͬʱÓдóµ½Ð¡ÅÅÐò
else return a.x < b.x;
}
int dp[];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
scanf("%d%d",&rect[i].x,&rect[i].y);
dp[i]=INF;
}
sort(rect,rect+n,comp);
for(int i=;i<n;i++)
*lower_bound(dp,dp+n,rect[i].y)=rect[i].y;
printf("%d\n",lower_bound(dp,dp+n,INF)-dp);
} return ;
}
DAG上的DP的更多相关文章
- UVA - 10131Is Bigger Smarter?(DAG上的DP)
题目:UVA - 10131Is Bigger Smarter? (DAG) 题目大意:给出一群大象的体重和IQ.要求挑选最多的大象,组成一个序列.严格的体重递增,IQ递减的序列.输出最多的大象数目和 ...
- BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998 题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置 ...
- NYOJ16 矩形嵌套 【DAG上的DP/LIS】
矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c ...
- UVA 10917 Walk Through the Forest(dijkstra+DAG上的dp)
用新模板阿姨了一天,换成原来的一遍就ac了= = 题意很重要..最关键的一句话是说:若走A->B这条边,必然是d[B]<d[A],d[]数组保存的是各点到终点的最短路. 所以先做dij,由 ...
- BZOJ 4011 HNOI2015 落忆枫音 DAG上的dp(实际上重点在于分析)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4011 题意概述:给出一张N点的DAG(从1可以到达所有的点),点1的入度为0.现在加一条原 ...
- UVA 11324 The Largest Clique(缩点+DAG上的dp)
求最大团.和等价性证明有类似之处,只不过这个不是求互推,而是只要a->b,或b->a即可. 同样的,容易想到先缩点,得到DAG,每个节点上保存SCC的点数,相信任意一条由根节点(入度为零) ...
- Codeforces 919D Substring ( 拓扑排序 && DAG上的DP )
题意 : 给出含有 N 个点 M 条边的图(可能不连通或者包含环),每个点都标有一个小写字母编号,然后问你有没有一条路径使得路径上重复字母个数最多的次数是多少次,例如图上有条路径的顶点标号顺序是 a ...
- (板子)缩点 + DAG上的DP(深搜)luogu P3387
板子传送门 根据题目意思,我们只需要找出一条点权最大的路径就行了,不限制点的个数.那么考虑对于一个环上的点被选择了,一整条环是不是应该都被选择,这一定很优,能选干嘛不选.很关键的是题目还允许我们重复经 ...
- UVa1025 (DAG上的dp)
这是紫书上的第一个dp哈. 1.状态定义:dp[i][j]---->到时刻i的时候(出发的时候时刻为0,约定时间为时刻time),从j号车站开往N号车站,在车站等待的最少的时间. 2.这个人当前 ...
随机推荐
- C# Window编程随记——ClickOnce程序部署
关于ClickOnce我们要说的主要有一下两点: 什么是ClickOnce? ClickOnce的使用 一.什么是ClickOnce(来自百度) ClickOnce 是一种部署技术,使 ...
- 树莓派 Zero W——随身钥匙扣
前言 原创文章,转载引用务必注明链接.水平有限,如有疏漏,欢迎指正. 本文使用Markdown写成,为获得更好的阅读体验和正确的格式显示,请访问我的博客原文: http://www.cnblogs.c ...
- openshifit 安装 redis
http://blog.csdn.net/lsx991947534/article/details/48860537 http://blog.csdn.net/aguangg_6655_la/arti ...
- Linux多线程编程的条件变量
在stackoverflow上看到一关于多线程条件变量的问题,题主问道:什么时候会用到条件变量,mutex还不够吗?有个叫slowjelj的人做了很好的回答,我再看这个哥们其他话题的一些回答,感觉水平 ...
- anaconda的所有版本大全--下载地址
地址: https://repo.continuum.io/archive/ 内容: Anaconda installer archive Filename Size Last Modified MD ...
- Android获取手机方向
假设用户开启了设置里的屏幕旋转,Android中处理横竖屏切换,通常的做法是在AndroidManifest.xml中定义android:configChanges="orientation ...
- C# 打开指定的目录 记住路径中 / 与 \ 的使用方法
老生常谈的问题了,C#在指定目录时,路径中要使用 \\.直接看实例 using System; namespace OpenFile{ class OpenFile{ static void Main ...
- 九度OJ 1094:String Matching(字符串匹配) (计数)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1259 解决:686 题目描述: Finding all occurrences of a pattern in a text is a p ...
- 初识代码封装工具SWIG(回调Python函数)
这不是我最早使用swig了,之前在写Kynetix的时候就使用了swig为python封装了C语言写的扩展模块.但是当时我对C++还不是很了解,对其中的一些概念也只是拿来直接用,没有理解到底是什么,为 ...
- 无法启动FTP站点,服务目前停止
在本地搭建了一个FTP服务器(windows搭建FTP服务器实战),再启动的时候提示错误: 错误提示信息: 根据提示可以查出问题原因:FTP服务没有开启 启动服务,再次重启站点服务.一切OK. 亲测好 ...