DP经典应用(四)二维最长上升子序列问题——矩形嵌套问题
来源:互联网 发布:查看一个ip绑定的域名 编辑:程序博客网 时间:2024/05/22 22:42
矩形嵌套问题
问题描述:输入多个矩形的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a < c,b < d或者b < c,a < d,任务是选出尽可能多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内求出最多嵌套矩形的个数。
注意加粗的一段话,就要求我们必须先排序。
样例输入:
1101 22 45 86 107 93 15 812 109 72 2
样例输出:
5
分析:
这个问题是不是和最长递增子序列的问题十分类似。
只不过这个子序列的数不只是一个数,而是长和宽罢了。
所以只要会转换一下就十分简单了。
依然按照分析动态规划的3个步骤:
按照3个步骤:
1.刻画最优解结构特征:
定义dp[i]为以第i个矩形pi为末尾的整个矩形序列中能够被嵌套的最多数目2.递归地定义最优解的值:
以第i个矩形pi为末尾元素的序列是:
1.只包含第i个矩形pi的序列
2.如果满足j < i 并且 pj.l < pi.l && pj.w < pi.w这个条件的以pj为末尾的序列末尾再加上pi后得到的新序列。
这两者之一。
所以得到此递推式:
dp[i] = max(dp[i],dp[j]+1) (j < i 且 pj.l < pi.l && pj.w < pi.w)3.计算最优解的值(递推)
代码如下:
#include<cstdio>#include<algorithm>using namespace std;const int maxn = 100;struct P{ int l,w;}p[maxn];int max(int a,int b){ return a>b?a:b; }int min(int a,int b){ return a<b?a:b; }int cmp(const P& a,const P& b){ if(a.l<b.l) return 1; else if(a.l==b.l&&a.w<b.w) return 1; else return 0; }int dp[maxn];int main(){ int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=0;i<n;i++) { int a,b; scanf("%d%d",&p[i].l,&p[i].w); a = max(p[i].l,p[i].w); b = min(p[i].l,p[i].w); p[i].l = a; p[i].w = b;//长大于宽 } sort(p,p+n,cmp); for(int i=0;i<n;i++) { dp[i] = 1; for(int j=0;j<=i;j++) { if(p[j].l<p[i].l&&p[j].w<p[i].w) { dp[i] = max(dp[i],dp[j]+1); } } } int ans=dp[0]; for(int i=0;i<n;i++) { if(ans<dp[i]) ans = dp[i]; } printf("%d\n",ans); } return 0; }
0 0
- DP经典应用(四)二维最长上升子序列问题——矩形嵌套问题
- 矩形嵌套 简单DP 最长上升子序列
- DP经典应用(二)最长递增子序列问题
- 矩形嵌套 ( 图和最长不上升子序列)
- nyist 16 矩形嵌套(最长上升子序列变形)
- 经典DP——最长上升子序列
- 最长上升子序列问题-动态规划(DP)
- 动态规划(DP)之最长上升子序列问题
- 最长上升子序列(LIS)问题
- 最长上升子序列问题(LIS)
- 最长上升子序列问题(LIS)
- 最长上升子序列问题(LIS)
- 最长上升子序列问题(LIS)
- 最长公共子序列问题 经典DP
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 最长上升子序列问题
- 设计模式(四)-工厂模式-简单工厂
- 剑指offer-调整数组顺序使奇数位于偶数前面
- 内核探测工具systemtap简介
- Ubuntu下编译linux-0.00
- VMwarePro 12教程 简洁明快不装逼 快速学会使用虚拟机
- DP经典应用(四)二维最长上升子序列问题——矩形嵌套问题
- 程序员面试经典--链表环路检测与入口结点返回
- android绘图之canvas
- 搜索引擎
- sqlyog企业版 v8.32注册码
- html页面制作特殊技巧
- 移动数据和移动计算(本地计算)的区别
- css自动旋转功能
- JAVA环境变量的设置