4-14 嵌套箱问题
问题描述
一个d维箱
嵌入另一个d维箱
是指存在
的一个 排列
,使得
。
(1)证明上述箱嵌套关系具有传递性;
(2)试设计一个有效算法,用于确定一个 d 维箱是否可嵌入另一个 d 维箱;
(3)给定由 n 个 d 维箱组成的集合
,试设计一个有效算法找出这 n 个 d维箱中的一个最长嵌套箱序列,并用 n 和 d 描述算法的计算时间复杂性。
给定由 n 个 d 维箱,试设计一个有效算法,找出这 n 个 d 维箱中的一个最长嵌套箱序列。
数据输入:
含多个测试项。每个测试数据项的第一行中有 2 个整数 n 和 d,分别表示箱的个数和维数。其后 n 行每行有 d 个正整数,表示箱的各维的长度。
Java
import java.util.Arrays;
import java.util.Scanner;
public class QianTaoXiang {
private static int MAX = 50;
private static int[][] box = new int[MAX][MAX];
private static int[][] a = new int[MAX][MAX]; //a[i][n]表示i的高度,如i嵌套j,a[i][j]=1
private static int[] x = new int[MAX]; //最长嵌套箱序列
private static int n, d;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
n = input.nextInt();
d = input.nextInt();
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < d; j++) {
box[i][j] = input.nextInt();
}
}
int count = load();
System.out.println();
System.out.println("最长嵌套箱序列长度为: " + count);
System.out.print("最长嵌套箱序列为: ");
for (i = count - 1; i >= 0; i--)
System.out.print(x[i] + 1 + " ");
}
}
//如果i嵌入j,返回1,如果j嵌入i,返回-1,如无嵌套关系,返回0
private static int nest(int i, int j) {
//将各维度排序
Arrays.sort(box[i], 0, d);
Arrays.sort(box[j], 0, d);
int l;
if (box[i][0] < box[j][0]) {
for (l = 1; l < d; l++)
if (box[i][l] >= box[j][l])
return 0;
return 1;
} else {
for (l = 1; l < d; l++)
if (box[i][l] <= box[j][l])
return 0;
return -1;
}
}
//递归修改嵌套箱深度值
//i嵌入j
private static void addHeight(int i, int j) {
if (a[i][n] == a[j][n]) { //如果i与j的深度相同
a[j][n]++;
}
int k;
for (k = 0; k < n; k++)
if (a[j][k] == 1) //j嵌入k
addHeight(j, k); //k的高度增加
}
//寻找最大深度的箱子作为首嵌套箱
private static int findMax() {
int i;
int max = a[0][n];
int maxIndex = 0;
for (i = 1; i < n; i++)
if (a[i][n] > max) {
max = a[i][n];
maxIndex = i;
}
return maxIndex;
}
//输出最长嵌套箱序列
private static int trace(int maxIndex) {
int m;
int count = 0;
int index = maxIndex;
int i;
x[count++] = index;
int temp = 0;
while (a[index][n] > 0) {
m = 0;
for (i = 0; i < n; i++)
if (a[i][index] == 1 && a[i][n] >= m) //如果i嵌入index,且i的高度最高
{
m = a[i][n];
temp = i;
}
index = temp;
x[count++] = index;
}
return count--;
}
//计算嵌套关系,结点高度
private static int load() {
//计算嵌套关系
int i, j;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
a[i][j] = nest(i, j);
//递归修改嵌套深度
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
if (a[i][j] == 1) //如果i嵌入j
addHeight(i, j); //增加j的高度
//寻找最大深度的箱子作为首嵌套箱
int maxIndex = findMax();
//输出最长嵌套箱序列
return trace(maxIndex);
}
}
Input & Output
5 2
3 7
8 10
5 2
9 11
21 18
8 6
5 2 20 1 30 10
23 15 7 9 11 3
40 50 34 24 14 4
9 10 11 12 13 14
31 4 18 8 27 17
44 32 13 19 41 19
1 2 3 4 5 6
80 37 47 18 21 9
最长嵌套箱序列长度为: 5
最长嵌套箱序列为: 3 1 2 4 5
最长嵌套箱序列长度为: 4
最长嵌套箱序列为: 7 2 5 6
Reference
王晓东《计算机算法设计与分析》
https://blog.csdn.net/u012319493/article/details/50009441