专题三1005

题目大意:

题目的大意是这样的,程序输入第一行是一个正整数N,代表不同的长方体的个数(注意:每种长方体的数量是不限的),然后下面有N行,每行有3个正整数,代表长方体的长、宽和高,定义规则:采用堆积木的方式将这些长方体摞在一块,要求上方的长方体的长和宽要严格小于下方的长方体的长和宽,然后要求编程输出用所给的这些长方体能堆起来的最高的高度。

解题思路:

兵来将挡水来土掩,我们先来看一下题目大意,每行的三个整数代表长方体的长、宽和高,长方体如果堆在一起的话,我们知道一种长方体有三种不同的堆放方式,每种方式就相当于一个新的长方体,因为它堆起的高度就会变化,然后我把长方体定义了一个结构体,当中的属性有长宽高和面积,之后定义一个长方体的结构体数组,从元素下标0开始赋值规则如下:针对一种长方体,将三个数选两个作为长和宽,从而就确定了其面积,而这个长方体堆起的高度就是另外一个数,因此,对于输入的每一种长方体,都有三个数组元素去存储其堆起的不同形态,然后按照面积从大到小排序,接下来便是动态规划的问题了,这其实是一个01背包问题,只是多了长宽大小的规则,用01背包的状态转移方程就可以解决了。

感想:

这一题的题干太长了,而且又是英文的,单凭我自己的英语水平去理解它简直就是不可能的。百度了一下题目大意觉得理解的差不多了,但是做的时候还是战战兢兢的,感觉有点无从下口的意思,真正想到了用01背包的时候就觉得豁然开朗了。

代码如下:

#include<iostream>

#include<algorithm>

using namespace std;

struct Block

{

int area;

int length;

int width;

int height;

};

bool cmp(Block a, Block b)

{

return a.area > b.area;

}

int main()

{

int l, w, h;

Block bk;

Block block[91];

int height[91];

int type;

int s = 1;

while (1)

{

cin >> type;

if (type == 0)break;

int k = 0;

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

{

cin >> l >> w >> h;

bk.length = l;

bk.width = w;

bk.area = l*w;

bk.height = h;

block[k++] = bk;

bk.length = l;

bk.width = h;

bk.area = l*h;

bk.height = w;

block[k++] = bk;

bk.length = h;

bk.width = w;

bk.area = h*w;

bk.height = l;

block[k++] = bk;

}

sort(block, block + type * 3, cmp);

height[0] = block[0].height;

for (int i = 1; i < type * 3; i++)

{

height[i] = block[i].height;

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

{

if ((block[i].length < block[j].length&&block[i].width < block[j].width) || (block[i].length < block[j].width&&block[i].width < block[j].length))

if (height[j] + block[i].height > height[i])

height[i] = height[j] + block[i].height;

}

}

int max = 0;

for (int i = 0; i < type * 3; i++)

{

if (height[i] > max)

max = height[i];

}

cout << "Case "<<s<<": maximum height = "<<max << endl;

s++;

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值