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 ... 
随机推荐
- BZOJ2242  [SDOI2011]计算器   【BSGS】
			2242: [SDOI2011]计算器 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 4741 Solved: 1796 [Submit][Sta ... 
- HDU 4417 离线+树状数组
			Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ... 
- [codeforces/edu3]总结
			链接:http://codeforces.com/contest/609 A题: 贪心,从大到小选. B题: 考虑对立面.$C_{sum}^2-\sum{C_{a_i}^2}$ C题: 最终状态是确定 ... 
- UVA10600:ACM Contest and Blackout(次小生成树)
			ACM Contest and Blackout 题目链接:https://vjudge.net/problem/UVA-10600 Description: In order to prepare ... 
- ubuntu下安装golang
			1.安装 sudo apt-get install golang 2.查看go的安装路径 go env 查看 GOROOT="/usr/lib/go-1.6" 3.修改环境变量 e ... 
- mapper.xml配置读取不到
			通常我们在sping的配置文件中,扫描到mapper文件,但是mapper.xml找不到,此时解决办法就是在pom中添加下面代码: <resources> <resource> ... 
- c++11新特性之nullptr
			在c++11中,nullptr可完全代替NULL. 然而NULL和nullptr还是稍有不同,NULL可被转化为int类型,而nullptr不能.因此nullptr对NULL在进行模板推导或者函数重 ... 
- HDU4027 线段树
			Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65768/65768 K ... 
- mybatis 热部署xml文件(spring boot和springmvc两种方式)
			参考:http://thinkgem.iteye.com/blog/2304557 步骤:1.创建两个java类 (1)MapperRefresh.java :用于刷新mapper (2)SqlS ... 
- JS语句循环(100以内奇偶数、100以内与7先关的数、100以内整数的和、10以内阶乘、乘法口诀、篮球弹起高度、64格子放东西)
			3.循环 循环是操作某一个功能(执行某段代码). ①循环四要素: a 循环初始值 b 循环的条件 c 循环状态 d 循环体 ②for循环 a 穷举:把所有的可能性的都一一列出来. b 迭代:每次循环都 ... 
