uva 437
来源:互联网 发布:网络拓扑visio图库 编辑:程序博客网 时间:2024/05/29 04:44
题目概述:
用砖堆柱子,有kind种砖,每种砖都是长方体,长宽高分别为x,y,z,同一种砖的三个参数可以互换位置,最底层(地面)可放任意砖,但只有底面的长和宽(前两个参数)分别小于下层的,才可以放在下层的砖上面,并将这块砖的高(第三个参数)加到柱子的高度中
输入:
第一行kind,其后kind行每行x,y,z,多组数据之间没有空行,输入以0为一行结束
限制:
0<n<=30
输出:
每行一个字符串,若用%times%表示第times组数据(times从1开始),%ans%表示可以堆成的最高的柱子的高度,则字符串为
Case %times%: maximum height = %ans%
注意冒号右侧有空格,等号左右均有空格,%ans%后无空格
样例输入:
1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0
样例输出:
Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342
讨论:
这个题的一个小难点在于如何高效存储砖的数据,一个比较低效的实现是每种砖存一次,利用函数(或成员函数)在一砖砖内部三个参数互换后进行比较
从抽象模型上,可以视为有向无环的节点加权图,也可以看做简单的递归,但无论如何,着实有记忆化的思想
1.这里将每种砖的三个参数分别左移(不是<<运算符)一次,作为三种砖存储,由于check函数可以检查前两个参数互换的情况,因而少存了三次,也因此n只有30,而数组开到100
题解状态:
0 KB,0 ms,C++11 4.8.2,1383
#include<cmath>#include<cctype>#include<cstring>#include<algorithm>#include<cstdio>#include<numeric>#include<vector>#include<set>#include<map>#include<queue>#include<list>#include<stack>using namespace std;struct node{int x;int y;int z;};node nodes[100];//用于存放每种砖的数据int kind;//由于深搜需要知晓种数,为方便作为全局变量int mem[100];//memory,存放从nodes中某种砖开始深搜所得最优解inline bool ck(node &a, node &b)//check,检查是否能将一块砖放在另一块上方,可以检查长宽互换后的情况{return (a.x > b.x&&a.y > b.y) || (a.x > b.y&&a.y > b.x);}inline int maxx(int a, int b)//专用的max函数,敲了很多次,已经很熟练了{return a > b ? a : b;}int dfs(node &a, int b)//深搜,第二个参数是砖a在nodes里的序号,在迭代时一并传递,作为mem数组下标{int biggest = 0;//初始化深搜所得最优解为0for (int p = 0; p < 3 * kind; p++) {//选择一块要放在上方的砖,因此深搜最深的砖是底面长宽最小的那个if ((ck(a, nodes[p]))) {//判断能否放在上方if (mem[p] != -1) {biggest = maxx(biggest, mem[p]);//最优解已知,直接返回结果} else {biggest = maxx(biggest, dfs(nodes[p], p));//最优解未知,深搜}}}mem[b] = biggest + a.z;//退出深搜前将最优解记录return mem[b];//返回上层深搜}int fun(int kind){for (int p = 0; p < kind; p++) {int x, y, z;scanf("%d%d%d", &x, &y, &z);//inputnodes[p].x = x, nodes[p].y = y, nodes[p].z = z;nodes[p + kind].y = x, nodes[p + kind].z = y, nodes[p + kind].x = z;nodes[p + 2 * kind].z = x, nodes[p + 2 * kind].x = y, nodes[p + 2 * kind].y = z;//参见讨论1}int biggest = 0;//初始化最大值for (int p = 0; p < 3*kind; p++) {//从所有点开始深搜,由于深搜过一次后便在mem数组留下记录,因此多数深搜只是去读个数就返回biggest = maxx(biggest, dfs(nodes[p], p));}return biggest;}int main(void){//freopen("vs_cin.txt", "r", stdin);int times = 0;//记数据序号while (~scanf("%d", &kind) && kind) {//inputmemset(mem, -1, sizeof(mem));printf("Case %d: maximum height = %d\n", ++times, fun(kind));//output}}
EOF
- uva-1025、uva-437、uva-1347、uva-116、uva-12563
- UVa 437
- UVA 437
- uva 437
- UVa 437
- uva 437 hdu 1069
- uva 437 动态规划
- uva 437 dp
- UVA 437 巴比伦塔
- uva
- UVA
- UVA
- UVA
- uva
- UVA
- UVA
- UVA
- UVA
- referrer地重要性
- 使用ViewPager和Fragment实现底部导航滑动重构版
- jsp页面报 $ is not defined
- 1685: Route Planning
- 利用索引优化查询,提高效率
- uva 437
- colorAccent,colorPrimary,colorPrimaryDark
- Sketch
- 前端要给力之:代码可以有多烂?
- start.S解析11
- 第八周项目33-对类中深复制的体验
- unix网络编程---读书笔记(一)---tcp/udp/sctp简介
- 链表中倒数第k个结点
- eclipse中 将java项目转换为web项目