HDU1069(最长单调递减数列)

告诉你n种规模的长方体的长,宽,高,每种规模的长方体个数不限,问你最多能搭多高的塔,塔是由这些长方体搭的,自上而下,每一块长方体都要比在它下面的长方体的规模小,即长和宽都比下面的长方体要小。注意长方体是可以调整的。

就是按照长和宽来排序,找最长的单调递减的数列。我们用dp[i]来表示搭建到第i块长方体的时候塔的最高高度,那么状态转移方程就是dp[i]=max(dp[i],dp[j]+s[i].h);

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <stack>
#include <set>
#define M 100000+5
#define LL long long
#define Ld __int64
#define eps 0.00001
#define INF 999999999
#define MOD 112233
#define MAX 26
#define PI acos(-1.0)
using namespace std;

struct solid
{
	int l,w,h;
}s[155];

bool cmp(solid a,solid b)
{
	if(a.l==b.l)
	{
		if(a.w==b.w)
			return a.h>b.h;
		return a.w>b.w;
	}
	return a.l>b.l;
}

int main()
{
	int n,cont=1;
	int d[3];
	int dp[155];
	while(~scanf("%d",&n),n)
	{
		int k=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d%d",&d[0],&d[1],&d[2]);
			sort(d,d+3);
			s[k].l=d[2],s[k].w=d[1],s[k++].h=d[0];		//各种长方体
			s[k].l=d[2],s[k].w=d[0],s[k++].h=d[1];
			s[k].l=d[1],s[k].w=d[0],s[k++].h=d[2];
		}
		sort(s,s+k,cmp);
		for(int i=0;i<k;i++)			//初始化为各自的高度
			dp[i]=s[i].h;
		for(int i=k-2;i>=0;i--)
		{
			for(int j=i+1;j<k;j++)
			{
				if(s[i].l>s[j].l && s[i].w>s[j].w)
				{
					dp[i]=max(dp[i],dp[j]+s[i].h);
				}
			}
		}
		int ans=-1;
		for(int i=0;i<k;i++)		//找最大高度
			ans=max(ans,dp[i]);
		printf("Case %d: ",cont++);
		printf("maximum height = %d\n",ans);
	}
	return 0;
}

HDU1069(最长单调递减数列),布布扣,bubuko.com

时间: 2024-12-20 12:37:33

HDU1069(最长单调递减数列)的相关文章

Refactoring之——代码的坏味道(四)过长参数列

1.1.4 Long Parameter List(过长参数列) 特征:一个方法有超过三四个的参数. 问题原因: 过长参数列可能是将多个算法并到一个函数中时发生的.函数中的入参可以用来控制最终选用哪个算法去执行. 过长参数列也可能是解耦类之间依赖关系时的副产品.例如,用于创建函数中所需的特定对象的代码已从函数移动到调用函数的代码处,但创建的对象是作为参数传递到函数中.因此,原始类不再知道对象之间的关系,并且依赖性也已经减少.但是如果创建的这些对象,每一个都将需要它自己的参数,这意味着过长参数列.

POJ 1552 BUY LOW, BUY LOWER(最长单调递减子序列求方案数)

BUY LOW, BUY LOWER Time Limit: 1000MS   Memory Limit: 30000K       Description The advice to "buy low" is half the formula to success in the bovine stock market.To be considered a great investor you must also follow this problems' advice: "

最长单调递减子序列

问题描述:求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}. 思路:这是一个标准的动态规划的问题,在不理解算法的时候,最感觉可以使用递归的思想,其实也是正确的,在最后给出一个递归的方法,在知道是动态规划问题以后,就需要进行分析,我们需要一个辅助数组记录信息,假如源数组为src,辅助数组为table,table[i]数组中记录着到src[0]~src[i]这个子数组中包含src[i]构成的最长单调子序列的长度(一定要注意就是table[i]

[小米OJ] 4. 最长连续数列

思路: 时间限制为O(n),即不能使用先排序后寻找的方法. 这里利用哈希表查询插入复杂度都为O(1)的特性来解,利用一个哈希表来保存每一个数字以及其所在数列的长度. 遍历每一个数字n:查询表中是否存在n-1和n+1,若存在,则hash[n]的值为1 + hash[n-1] + hash[n+1],若不存在即是 1. 同时,为了预防相同数字多次判断,每一次遍历时判断该数字在表中的value是否为0,若不为0说明已经判断过了,跳过即可. #include <bits/stdc++.h> using

HDU1069 最长上升子序列

emm....矩形嵌套 还记得吗....就是它... 直接贴代码了.... import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Scanner; public class Main{ final static int maxn = 1000000; final static int INF =

【蓝桥杯】最长等差素数数列

[题目] 在小于10的素数中有3.5.7组成的等差数列,在小于30的素数中有11.17.23.29组成的等差数列. 试找出区间[100,1000]内的素数构成的最大等差数列(即等差数列包含的素数个数最多)并打印输出. [关键字] 素数:等差数列 [思路] 先用一个数组标记出 100 ~ 1000 之间哪些是素数: 差值从 2 ~ 900 进行循环判断 [实现] 1 #include <stdio.h> 2 #define N 1001 3 #define MAX_CHA 900 4 5 voi

动态规划(4)———最长上升子序列(拦截导弹NYOJ79)

拦截导弹 描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于等于前一发的高度.某天,雷达捕捉到敌国导弹来袭.由于该系统还在试用阶段,所以只用一套系统,因此有可能不能拦截所有的导弹. 输入 第一行输入测试数据组数N(1<=N<=10)接下来一行输入这组测试数据共有多少个导弹m(1<=m<=20)接下来行输入导弹依次飞来的高度,所有高度值均是大于0的正整数. 输出 输出最多能拦截的

poj 1952 BUY LOW, BUY LOWER[最长单调子序列变形]

题目:poj 1952 BUY LOW, BUY LOWER 题意:给出一个序列,先求最长单调递减子序列,然后求在子序列最长的情况下,不同的长度都为最长的的子序列的个数.(比如3,2,1和3,2,1属于相同,只能算一个) 分析:首先用一个dp[i]表示到当前i点的最长子序列的长度 用dp2[i]表示最长为dp[i]的子序列的个数 然后dp[i] = max(dp[j])+1 (1<=j /************************************ Problem: 1952 Use

PTA(Basic Level)1030.完美数列

给定一个正整数数列,和正整数 p,设这个数列中的最大值是 M,最小值是 m,如果 M≤*m**p*,则称这个数列是完美数列. 现在给定参数 p 和一些正整数,请你从中选择尽可能多的数构成一个完美数列. 输入格式: 输入第一行给出两个正整数 N 和 p,其中 N(≤105)是输入的正整数的个数,p(≤109)是给定的参数.第二行给出 N 个正整数,每个数不超过 109. 输出格式: 在一行中输出最多可以选择多少个数可以用它们组成一个完美数列. 输入样例: 10 8 2 3 20 4 5 1 6 7