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 ...
随机推荐
- Hyperledger Fabric 实战(十): Fabric node SDK 样例 - 投票DAPP
Fabric node SDK 样例 - 投票DAPP 参考 fabric-samples 下的 fabcar 加以实现 目录结构 . ├── app │ ├── controllers │ │ └─ ...
- Windows系统中Xshell与Linux连接时遇到的问题
前提条件:在Windows系统中已经安装了Xshell,并且安装了虚拟机软件和Linux系统 步骤1.在Linux系统中root用户下,使用ifconfig命令查看虚拟系统Linux的IP地址.如图1 ...
- BZOJ4873 [Shoi2017]寿司餐厅 【最大权闭合子图】
题目链接 BZOJ4873 题解 题意很鬼畜,就可以考虑网络流[雾] 然后就会发现这是一个裸的最大权闭合子图 就是注意要离散化一下代号 #include<algorithm> #inclu ...
- bzoj3810: [Coci2015]Stanovi(记忆化搜索)
实际上切出来的矩阵在原矩阵上的位置是不重要的...重要的只有矩阵的大小和上下左右是否在边界上. 于是我们可以设f[x][y][l][r][u][d]表示x*y的矩阵上下左右是不是边界的最小代价. 记忆 ...
- 剑桥offer(11~20)
11.题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. class Solution { public: int NumberOf1(int n) { ; unsigned ...
- shell中的数值运算
By francis_hao Oct 2,2017 本文摘录自bash的man手册. 算数运算相关的形式 形式 含义 ((expression)) expression按照下面描述的算术 ...
- 获取 exception 对象的字符串形式(接口服务返回给调用者)
工具类: package com.taotao.common.utils; import java.io.PrintWriter; import java.io.StringWriter; publi ...
- ASP.NET基础学习未整理随笔
利用新建网站添加的项目可以改完代码直接刷新就行 提交到服务程序的表单一定要具有name.<input type="hidden"value="true"n ...
- c# 计算时间差---天数
---处理两个时间相差的天数 测试数据:三个时间 DateTime dt1 = Convert.ToDateTime("2017-03-17 09:49:55.667"); Dat ...
- ICPC2017 Urumqi - K - Sum of the Line
题目描述 Consider a triangle of integers, denoted by T. The value at (r, c) is denoted by Tr,c , where 1 ...