Uva 103 Stacking Boxes (DP_最长递增子序列)

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=114&page=show_problem&problem=39


题目大意:给定n个m维箱子,每个箱子有个值,箱子各维数字可以交换。如果某个箱子的每一维都比另外i一个箱子小,那另一个箱子就可以装下这个箱子,问哪哥箱子装的箱子最多,装几个?最后将装在一起的箱子按体积从小到大的顺序输出。


解题思路:状态转移方程很容易想:if (big[j][i] ) dp[j] = max(dp[j],dp[i] + 1) (如果第j个箱子比i大,dp[i]表示装得最多的箱子数)。这个big[j][i]要先算出来,然后直接用就好,就相当于一维数组里的数字大小关系一样。在算big[j][i]之前要先对各个箱子各维的数字排序,然后再对各个箱子按最小一维排序。


测试数据:

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


代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAX 100


struct node {

	int in,arr[MAX];
}box[MAX];


int cmp(node a,node b) {

	return a.arr[1] < b.arr[1];
}


int main()
{
	int ansi,path[MAX];
	int ans,big[MAX][MAX];
	int i,j,k,n,m,dp[MAX];


	while (scanf("%d%d",&n,&m) != EOF) {

		for (i = 1; i <= n; ++i) {

			box[i].in = i;
			for (j = 1; j <= m; ++j) 
				scanf("%d",&box[i].arr[j]);
		}
		

		for (i = 1; i <= n; ++i)
			sort(box[i].arr+1,box[i].arr+1+m);
		sort(box+1,box+1+n,cmp);
		memset(dp,0,sizeof(dp));
		memset(big,0,sizeof(big));


		for (i = 2; i <= n; ++i)
			for (j = 1; j < i; ++j) {

				for (k = 1; k <= m; ++k)
					if (box[i].arr[k] <= box[j].arr[k]) break;
				if (k == m + 1) big[i][j] = 1; 
			}

		
		ans = ansi = 1;
		for (i = 1; i <= n; ++i) 
			dp[i] = 1,path[i] = i;
		for (i = 2; i <= n; ++i) {

			for (j = 1; j < i; ++j) 
				if (big[i][j] && dp[j] + 1 > dp[i])
					 dp[i] = dp[j] + 1,path[i] = j;
			if (dp[i] >= ans) ans = dp[i],ansi = i;
		}

		
		printf("%d\n",ans);
		k = 1;
		while (1) {
		
			dp[k++] = ansi;
			if (ansi == path[ansi]) break;
			ansi = path[ansi];
		}
		for (i = k - 1; i >= 1; --i)
			printf(i == 1 ? "%d\n" : "%d ",box[dp[i]].in);
	}
}

本文ZeroClock原创,但可以转载,因为我们是兄弟。

你可能感兴趣的:(struct,测试,Path)