【java】嵌套矩形

来源:互联网 发布:说话技巧 叶名琛 知乎 编辑:程序博客网 时间:2024/06/08 18:10

有n个矩形,每个矩形可以用两个整数a,b表示,分别表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或b<c,a<d。

例如:1,5可以嵌套在6,2内,但不能嵌套在3,4内。

给出n个矩形,选出尽量多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。

先输入矩形的数目n,紧接着输入n行,每行代表一个矩形,最后输出选出的矩形。

样例输入:

6
1,2
4,3
4,6
3,17
7,8
10,11

样例输出:

1,2
4,3
4,6
7,8
10,11

思路:如果矩形X包含在矩形Y中,我们就从矩形X到Y连一条有向边;N个结点构成一个有向无环图DAG,我们的任务就是求DAG上的最长路径。

设d(i)表示从结点i出发的最长路径长度,则d(i)=max[d(j)+1|(i,j)∈E],其中E为边集。最终答案为所有d(i)中的最大值。

根据状态转移方程,可以尝试递推或记忆化搜索求解。对于状态递推顺序不容易确定时,记忆化搜索更方便一些。当终点固定时,递推更方便一些。

import java.util.Arrays;import java.util.Scanner;public class Main {public static int dpSolution(int[][] edg,int[] d,int index){if(d[index]>=0)return d[index];d[index]=1;for(int i=0;i<edg.length;i++){if(edg[index][i]==1){int temp=dpSolution(edg,d,i)+1;if(temp>d[index])d[index]=temp;}}return d[index];}public static void print(int[][] a,int[][] edg,int[] d,int index){System.out.println(a[index][0]+","+a[index][1]);for(int i=0;i<d.length;i++){if(edg[index][i]==1&&d[index]-d[i]==1){print(a,edg,d,i);break;}}}public static void main(String[] args){Scanner scanner = new Scanner(System.in);while(scanner.hasNext()){int n=scanner.nextInt();scanner.nextLine();int[][] a=new int[n][2];int[][] edg=new int[n][n];int[] d=new int[n];Arrays.fill(d, -1);for(int i=0;i<n;i++){String s=scanner.nextLine();String[] temp=s.split(",");a[i][0]=Integer.parseInt(temp[0]);a[i][1]=Integer.parseInt(temp[1]);}for(int i=0;i<n;i++){//用邻接矩阵存储各个矩形的包含关系for(int j=i+1;j<n;j++){if((a[i][0]<a[j][0]&&a[i][1]<a[j][1])||(a[i][1]<a[j][0]&&a[i][0]<a[j][1])){edg[i][j]=1;}else if((a[i][0]>a[j][0]&&a[i][1]>a[j][1])||(a[i][1]>a[j][0]&&a[i][0]>a[j][1])){edg[j][i]=1;}}}for(int i=0;i<n;i++){dpSolution(edg, d, i);}int max=0,num=0;for(int i=0;i<n;i++){if(d[i]>max){max=d[i];num=i;}}print(a,edg,d,num);}scanner.close();}}


0 0
原创粉丝点击