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 ...
随机推荐
- BZOJ1503:[NOI2004]郁闷的出纳员——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1503 (题面复制的洛谷的,因为洛谷好看) 题目描述 OIER公司是一家大型专业化软件公司,有着数以万 ...
- IE下textarea去除回车换行符
在textarea中回车,会产生转义字符\r\n,有些时候我们不需要这两个转移字符,也就是清空textarea.下面的方法并不是清空,但是能够起到差不多的效果. 如果在textarea中按回车,内容提 ...
- 2017-7-18-每日博客-关于Linux下的history的常用命令.doc
History history命令可以用来显示曾执行过的命令.执行过的命令默认存储在HOME目录中的.bash_history文件中,可以通过查看该文件来获取执行命令的历史记录.需要注意的是.bash ...
- iOS常用RGB颜色的色值
常用RGB颜色表 色值 R G B 值 R G B 值 R G B 值 黑色 0 0 0 #000000 黄色 255 255 0 #FFFF00 浅灰蓝色 176 224 230 #B0E0E6 ...
- BZOJ1105 [POI2007]石头花园SKA 贪心
[POI2007]石头花园SKA Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 776 Solved: 237[Submit][Status][Di ...
- zookeeper源码分析之leader选举
zookeeper提供顺序一致性.原子性.统一视图.可靠性保证服务zookeeper使用的是zab(atomic broadcast protocol)协议而非paxos协议zookeeper能处理并 ...
- crontab 定期拉取代码
* * * * * cd /home/wwwroot/default/lion/ && /usr/bin/git pull origin 5hao >> /tmp/git. ...
- liunx环境下安装mysql数据库2
mysql的安装和配置[1]解压mysql安装包,进入mysql目录,添加用户,并安装,将权限授权给mysql用户
- 怎么修改jar包中的class文件然后再重新打成jar包
1.导入到eclipse中, 修改完了 然后导出jar即可 2.jar cf file.jar *.class 将当前目录下所有CLASS文件打包成新的JAR文件 3.对于补丁.之前已经有jar 例如 ...
- tortoise svn冲突解决
Tortoiese svn 冲突解决 当文件被别人修改并提交到SVN服务器后,如果自己本地的文件没有被更新为最新的版本,而且已经做了修改,这时候提交将会被成功,系统会提示你的版本已经过期,并要求你先进 ...