U43597 积木
题目背景
小 XX 感到很无聊,从柜里翻出了小时候玩的积木。
题目描述
这套积木里共有 \(n\) 块,每块积木都是一个长方体。
小 X 想知道这些积木拼成一个积木塔(不必每一块 积木都使用)。
所谓积木塔,就是将积木一个一个摞起来,(除去最底层的积木外)每块积木的底面必须能被它下面的积木的底面完全包含(即对应的长宽都要更短或相等)。
当然,积木可以任意放置,即可以以任意一面作为底面。
现在小 X 想知道,积木塔最多能拼多高。
Solution
状态压缩Dp
\(f(i,j,k)\)表示状态为\(i\)顶为\(j\)且\(j\)的状态(那面朝上)的最大高度,
转移即可.
Code
// luogu-judger-enable-o2
#include <vector>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
struct Pair {
int a, b;
Pair(int _, int __) { a = _, b = __; }
bool operator <= (const Pair& o) const {
return (a <= o.a and b <= o.b) or (a <= o.b and b <= o.a);
}
};
struct cuboid {
int a, b, c;
cuboid() { }
void input() {
scanf("%d%d%d", &a, &b, &c);
}
Pair Choose(int p) {
return p ? (p < 2 ? Pair(a, b) : Pair(a, c)) : Pair(b, c);
}
bool LessOrEqual(cuboid o, int q, int p) {
Pair A = Choose(p), B = o.Choose(q);
return A <= B;
}
};
cuboid A[15];
std:: vector<int> Status[15];
int f[1 << 16][15][3];
int main () {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i += 1)
A[i].input();
int Max = (1 << n);
for (int i = 0; i < Max; i += 1)
Status[__builtin_popcount(i)].push_back(i);
for (int i = 0; i < n; i += 1)
f[1 << i][i][0] = A[i].a, f[1 << i][i][1] = A[i].c, f[1 << i][i][2] = A[i].b;
int res = 0;
for (int i = 1; i < n; i += 1) {
for (int j = 0; j < Status[i].size(); j += 1) {
int status = Status[i][j];
for (int k = 0; k < n; k += 1) {
if (status & (1 << k) == 0) continue;
for (int w = 0; w < 3; w += 1) {
if (not f[status][k][w]) continue;
res = std:: max(res, f[status][k][w]);
for (int l = 0; l < n; l += 1) {
if (status & (1 << l)) continue;
int sta = status ^ (1 << l);
if (A[l].LessOrEqual(A[k], w, 0))
f[sta][l][0] = std:: max(f[sta][l][0], f[status][k][w] + A[l].a);
if (A[l].LessOrEqual(A[k], w, 1))
f[sta][l][1] = std:: max(f[sta][l][1], f[status][k][w] + A[l].c);
if (A[l].LessOrEqual(A[k], w, 2))
f[sta][l][2] = std:: max(f[sta][l][2], f[status][k][w] + A[l].b);
}
}
}
}
}
for (int i = 0; i < n; i += 1)
res = std:: max(res, f[Max - 1][i][0]),
res = std:: max(res, f[Max - 1][i][1]),
res = std:: max(res, f[Max - 1][i][2]);
printf("%d\n", res);
return 0;
}
U43597 积木的更多相关文章
- codevs 3288 积木大赛
题目描述 Description 春春幼儿园举办了一年一度的"积木大赛".今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看成由 n 块宽度为1的积木组成,第i块积木的最终高度 ...
- 洛谷P2409 Y的积木
P2409 Y的积木 77通过 491提交 题目提供者zhouyonglong 标签云端评测 难度普及+/提高 提交 讨论 题解 最新讨论 这组数据几乎可以卡掉所有程- 第一个题解有点问题 求教大 ...
- NOIP2013积木大赛
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- vijos1059 积木城堡[n年浙江省队第X轮](背包的方案总数 or 01背包)
描述 XC的儿子小XC最喜欢玩的游戏用积木垒漂亮的城堡.城堡是用一些立方体的积木垒成的,城堡的每一层是一块积木.小XC是一个比他爸爸XC还聪明的孩子,他发现垒城堡的时候,如果下面的积木比上面的积木大, ...
- noip2013 积木大赛
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- BZOJ 1109: [POI2007]堆积木Klo
1109: [POI2007]堆积木Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 948 Solved: 341[Submit][Statu ...
- [NOIP2013] 提高组 洛谷P1969 积木大赛
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- NOIp 2013 #1 积木大赛 Label:有趣的模拟
题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...
- UVa 101 - The Blocks Problem(积木问题,指令操作)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
随机推荐
- BZOJ1058:[ZJOI2007]报表统计——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1058 https://www.luogu.org/problemnew/show/P1110#su ...
- 51nod 1554:欧姆诺姆和项链——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1554 题目: 有一天,欧姆诺姆发现了一串长度为n的宝石串,上面有五颜六色 ...
- printf函数用法小记
By francis_hao Aug 26,2017 C语言中printf函数是一个比较常用的函数,但是常用并不代表完全了解,本文翻译了printf的man手册,介绍了其全部功能(不包括ma ...
- 2017-7-19-每日博客-关于Linux下的CentOS中文件夹基本操作命令.doc
CentOS中文件夹基本操作命令 文件(夹)查看类命令 ls--显示指定目录下内容 说明:ls 显示结果以不同的颜色来区分文件类别.蓝色代表目录,灰色代表普通文件,绿色代表可执行文件,红色代表压缩文件 ...
- HDU 4348 主席树区间更新
To the moon Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- HDU1394 逆序数
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- 手脱ACProtect V1.4X(有Stolen Code)
1.载入PEID ACProtect V1.4X -> risco 首先需要说明的是,这个壳被偷取的代码非常多,如果去找的话会比较麻烦,所以我们换一种另类的方法,不脱壳也可以使用资源修改器对程序 ...
- CentOS 下安装 LEMP 服务(nginx、MariaDB/MySQL 和 php)
转载自:https://linux.cn/article-4314-1.html 编译自:http://xmodulo.com/install-lemp-stack-centos.html 作者: D ...
- 2015/9/1 Python基础(6):列表
列表和字符串类型很相似,是同样的序列式数据类型.但是字符串只能由字符组成,列表可以保留任意数目的Python对象的灵活的容器.Python的列表比C的数组要灵活,数组里面只能是一种类型,列表可以有多种 ...
- c# bootstrap-table 知识
bootstrap-table 提供手机端,电脑端访问,提供分页,筛选等. bootstrap-table说明文档:http://bootstrap-table.wenzhixin.net.cn/zh ...