nyoj--16 矩形嵌套(经典DP)
2016-02-27 11:37
399 查看
nyoj 16
其次,这个DAG的起点是不固定的,也就是说需要考虑从每个顶点出发所能得到的最长路。现在考虑某一点 i,设 d(i) 表示从结点 i 出发的最长路长度,因为它只能走到它的邻接点,所以状态转移方程为d(i)=max{d(j)+1|(i,j)∈E}
题意
有n个矩形,每个矩形可以用a,b来描述,表示长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或者b<c,a<d(相当于旋转X90度)。例如(1,5)可以嵌套在(6,2)内,但不能嵌套在(3,4)中。你的任务是选出尽可能多的矩形排成一行,使得除最后一个外,每一个矩形都可以嵌套在下一个矩形内。题解
按白书上的分析,矩形之间的“可嵌套”关系是一个二元关系,可以用图来建模。如果矩形X可以嵌套在矩形Y中,就从X到Y有一条有向边,这就转化为一个DAG,所要求的是DAG上的最长路径。其次,这个DAG的起点是不固定的,也就是说需要考虑从每个顶点出发所能得到的最长路。现在考虑某一点 i,设 d(i) 表示从结点 i 出发的最长路长度,因为它只能走到它的邻接点,所以状态转移方程为d(i)=max{d(j)+1|(i,j)∈E}
#include <iostream> #include <fstream> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1000 + 5; bool graph[maxn][maxn]; int a[maxn], b[maxn]; int n, t; int dp[maxn]; void buildGraph() { memset(graph, 0, sizeof(graph)); for(int i = 0; i < n; ++i) { for(int j = 0; j < n; ++j) { if((a[i] < a[j] && b[i] < b[j]) || (a[i] < b[j] && b[i] < a[j])) graph[i][j] = true; } } } int DP(int i) { int& ans = dp[i]; if(ans > 0) return ans; ans = 1; for(int j = 0; j < n; ++j) if(graph[i][j]) ans = max(ans, DP(j) + 1); return ans; } int main() { //fstream cin("data.in"); ios::sync_with_stdio(false); for(cin >> t; t--; ) { cin >> n; for(int i = 0; i < n; ++i) cin >> a[i] >> b[i]; buildGraph(); memset(dp, 0, sizeof(dp)); int ans = 0; for(int i = 0; i < n; ++i) ans = max(ans, DP(i)); cout << ans << endl; } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow