UVA 103 Stacking Boxes 套箱子 DAG最长路 dp记忆化搜索

题意:给出几个多维的箱子,如果箱子的每一边都小于另一个箱子的对应边,那就称这个箱子小于另一个箱子,然后要求能够套出的最多的箱子。

要注意的是关系图的构建,对箱子的边排序,如果分别都小于另一个箱子就说明是箱子小于,重载<即可。

然后就是正常的dp最长路的搜索了。

代码:

 

/*

*  Author:      illuz <iilluzen[at]gmail.com>

*  Blog:        http://blog.csdn.net/hcbbt

*  File:        uva103.cpp

*  Create Date: 2013-09-12 19:32:36

*  Descripton:  dp 

*/



#include <cstdio>

#include <algorithm>

#include <cstring>

using namespace std;



const int MAXN = 100;



struct Box {

	int dem;

	int e[30];

	void Sort() {

		sort(e, e + dem);

	}

	bool operator < (const Box& a) const {

		for (int i = 0; i < dem; i++)

			if (e[i] >= a.e[i])

				return false;

		return true;

	}

} b[MAXN];

int big[MAXN][MAXN], k, t;

int dp[MAXN];



int solve(int i) {

	if (dp[i] > 0) return dp[i];

	dp[i] = 1;

	for (int j = 0; j < t; j++)

		if (big[i][j])

			dp[i] = max(dp[i], solve(j) + 1);

	return dp[i];

}



void output(int i) {

	for (int j = 0; j < t; j++)

		if (big[i][j] && dp[i] == dp[j] + 1) {

			printf(" %d", j + 1);

			output(j);

			break;

		}

}



int main() {

	while (scanf("%d%d", &t, &k) != EOF) {

		for (int i = 0; i < t; i++) {

			for (int j = 0; j < k; j++) {

				b[i].dem = k;

				scanf("%d", &b[i].e[j]);

			}

			b[i].Sort();

		}

		memset(big, 0, sizeof(big));

		memset(dp, 0, sizeof(dp));

		for (int i = 0; i < t; i++)

			for (int j = 0; j < t; j++)

				if (i != j && b[i] < b[j])

					big[i][j] = 1;

		for (int i = 0; i < t; i++)

			solve(i);

		int tt = 0;

		for (int i = 0; i < t; i++)

			if (dp[i] > dp[tt])

				tt = i;

		printf("%d\n", dp[tt]);

		printf("%d", tt + 1);

		output(tt);

		printf("\n");

	}

	return 0;

}


 

 

你可能感兴趣的:(stack)