代码先锋网 代码片段及技术文章聚合

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;
}


版权声明:本文为qq_33974741原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33974741/article/details/84481358

智能推荐

DAG 模型 stacking boxes 动态规划

题目:UVA 103 stacking boxes 题目大意: 给你两个数,一个是盒子的个数,一个是每一个盒子的维数。将一个个盒子互相装起来,让你求最多可以装多少个,要求字典序最小。 解析:这个就是盒子的嵌套,和二维盒子嵌套有点像,只是建图的方法不一样,二维只要判断两个,长和宽即可,而k维需要判断k次,除此之外,其余都是一样的。 方法: 前提:dp[i]=max(dp[i],d(j)+1); 第一...

【UVa】【DP】1289 Stacking Plates

UVa 1289 Stacking Plates 题目 ◇题目传送门◆(由于UVa较慢,这里提供一份vjudge的链接) ◇题目传送门◆ 题目大意 有NN堆盘子,第ii堆盘子有hihi个,从上到下直径不减。有两种操作: split:将一堆盘子从某个位置分成上下两堆; join:将一堆盘子aa放在另一堆盘子bb上,要求aa底部的盘子直径不超过bb顶部盘子直径。 求将所有盘子叠成一堆的最少操作步数。 ...

UVA 1289 Stacking Plates——dp

拿到这道题目第一反应就是它很像汉诺塔问题,只是多了划分这个操作,因此第一步我们尝试把它简化成汉诺塔问题 首先明确一点,最终结果等于划分次数加合并次数。设划分次数为x,那么划分x次必然会形成n+x个堆,把这n+x个堆合并成1个堆需要n+x-1次合并操作,因此最终结果就是2*x+n-1,这样我们只用划分次数x就表示出了最终结果。不过为了使问题更接近汉诺塔问题,我们应该用合并次数来表示最终结果,设合并次...

UVA103DAG上最长路径+字典序输出

题目描述: 给定n维的m个物品,按照各维长度严格递增的排序,求最长的序列,并按照字典序输出。 例如n=4,(1 2 3 4)之后是(2,3,4,5)就可以。 思维过程: 《入门经典》上DAG模型。 枚举状态结点时,出现了思维误区。想要把n维的n个长度滚动成n种状态点。 上述考虑固然可以,但是不是n种状态点,因为是按顺序排列,所以是n!种,然而n《=30。 后来想到了贪心的优化,我们的重点是一个能嵌...

猜你喜欢

POJ 3249(记忆化搜索,,,,DAG最长路)

题目链接:http://poj.org/problem?id=3249  题目大意:给出n个点,m条边,每个点都提供了相对的点权值,然后给出相连着的边,问从起点走到终点最大利润值。起点是入度为0的点,终点是出度为0的点。 思路1:SPFA求最长路,正向建边TLE,反向建边4400msAC。。。。 2:记忆化搜索,每次都保存当前点到终点获得的最大利润。 AC代码,搜索 ....1844ms...

杂物_DAG最长路_DP

P1113 杂务 传送门 题目描述 John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它。比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及一些其它工作。尽早将所有杂务完成是必要的,因为这样才有更多时间挤出更多的牛奶。当然,有些杂务必须在另一些杂务完成的情况下才能进行。比如:只有将奶牛赶进牛棚才能开始为它清洗乳房,还有在未给奶牛清洗乳房之前不能挤奶。我们把这...

DAG最长路 uva437

题意:有n种立方体,每种无穷个。要求选一些立方体摞成一根尽量高的柱子,使得每个立方体的底面长宽严格小于它下方立方体的底面长宽 解析:实际上每种立方体只有三次使用机会,先做预处理,给n*3种立方体编号。因为是严格小于的,所以这个图是DAG,可以套用DAG最长算法。建图,G[i][j]表示i到j有一条连线,j在i的上方。d[i]表示以i为起点的最长高度。对于底面长宽最大的立方体来说,以它为起点的长度就...

【动态规划】UVA - 437 The Tower of Babylon题解(DAG+记忆化搜索DP)

难度等级:3 题目:UVA - 437 The Tower of Babylon 题意: 给出n种矩形石块,有x,y,z(长宽高),有无限个,小块往大块上堆叠(严格小,即上下面积不能相同),求用这些块堆叠的最大高度。 思路: 通过第一个样例可知,一块有三用,假设x<y<z,底部面积有3种情况:①(x,y,z)②(x,z,y)③(y,z,x) 每种有无限块。题目给出n块(n<=30...