题目描述
有 n 个矩形,每个矩形可以用 a,b来描述,表示长和宽。矩形 X(a,b)可以嵌套在矩形 Y(c,d)中当且仅当 a <c,b<d或者 b<c,a<d
(相当于旋转 90 度)。例如(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解题思路:d(i,G)这个函数,表示的是,从矩形i出发的最长路长度,递归最好是debug去走一走,不要太深究。
先用自己的脑袋想一想,如果是人为的去数嵌套的矩形,应该怎么数呢
找到一个矩形A,然后再找到比这个矩形还要大的矩形B,然后找到比B大的矩形C……依次这样找
那我们的最多矩形个数,是不是应该先找到最小的那个矩形,然后找下一个比他大一点的,依次。
得到的一个想法就是:转换成求最长路的问题!DFS!
import java.util.Scanner; public class Main { /** * @param args */ static int t[]; static int n=0; public static void main(String[] args) { // TODO Auto-generated method stub Scanner in=new Scanner(System.in); int N=in.nextInt();//N组数据 while(N-->0){ n=in.nextInt();//矩形的个数n int arr[][]=new int[n][2]; for(int i=0;i<n;i++) for(int j=0;j<2;j++){ arr[i][j]=in.nextInt();//把矩形的长和宽录入 } int G[][]=new int[n][n]; t=new int[n]; for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if((arr[i][0]<arr[j][0]&&arr[i][1]<arr[j][1])||(arr[i][0]<arr[j][1]&&arr[i][1]<arr[j][0])) G[i][j]=1;//如果满足题目条件,就表示,i可以放在j矩形里面,表示i和j是连通的 } int max=-1; for(int i=0;i<n;i++){//从第一个矩形开始遍历,然后走遍可以嵌套这个矩形的所有矩形 if(d(i,G)>max){//取最大的路径 max=d(i,G); } } System.out.println(max);} } private static int d(int i, int[][] G) { // TODO Auto-generated method stub int ans=t[i]; if(ans>0)return ans;//如果我已经走过i的所有连通图,那么我就直接返回,防止多遍历的情况,记忆划! ans=1;//每个矩形初始路径都是1撒 for(int j=0;j<n;j++){ if(G[i][j]==1){//如果j矩形和i矩形是连通 的,就接着走 ans=Math.max(ans, d(j, G)+1); //比较当前的路径和他所连通给的那个矩形的最长路径 t[i]=ans;//记忆化,给路径赋值。 } } return ans; } }
嵌套矩形问题(初级)算法竞赛紫书
最新推荐文章于 2020-10-21 10:55:01 发布