P5760

容易想到设 fi,j 表示前 i 块积木,把它们分成 j 堆柱子后高度之和的最大值 (第 i 块积木在第 j 堆柱子),

然后考虑第 i 块三种情况:

  1. 不放,什么都不用做

  2. 另起一个柱子,枚举第 j1 堆柱子的顶端 k,则

    fi,j=max(fi,j,fk,j1+highi)

  3. 加在前一个柱子之前,枚举第 i 块积木在第 k 块积木上,则

    fi,j=max(fi,j,fk,j+highi)

其中,highi 为第 i 块积木的高度,

高高兴兴地写完,交!听取 WA 声一片啊!

仔细想想:长方体可以通过旋转得到另一个长方体!

一个长方体可以最多可以 3 个不同的长方体,

令类型 0 为以 a,b 为底的长方体,

类型 1 为以为底的 b,c 长方体,

类型 2 为以 c,a 为底的长方体

其中,a,b,c 为题目中的意思,

fi,j,d 表示前 i 块积木,把它们分成 j 堆柱子,第 i 块积木类型为 d,的高度之和的最大值 (第 i 块积木在第 j 堆柱子)

这里 0d2

同上,分三种情况:

  1. 不放,什么都不用做

  2. 另起一个柱子,枚举第 j1 堆柱子的顶端 k,则

    fi,j,d1=max(fi,j,d1,fk,j1,d2+highi,d1)

  3. 加在前一个柱子之前,枚举第 i 块积木在第 k 块积木上,则

    fi,j,d1=max(fi,j,d1,fk,j,d2+highi,d1)

其中,d1,d2 分别为 i 的类型和 k 的类型,highi,d1id1 类型时的高度。

以下优化为 @asdfo123 大佬的方法:

为了方便,令 li,0,li,1,li,2 分别为题目所说的 a,b,c

在令li,3=li,0

li,4=li,1

则类型为 d 的第 i 个长方体的高为 li,d+2,长宽为 li,d 以及 li,d+1

这样在 highi,d 时和处理两个长方体堆在一起时是否合法就方便多了。

#include <cstdio>
#include <iostream>
using namespace std;

const int N = 110;

int l[N][5], f[N][N][5];

int length (int x, int d) { // 计算第 x 个长方体 d 类型的长方体的长
    return max (l[x][d], l[x][d + 1]);
}

int width (int x, int d) { // 计算第 x 个长方体 d 类型的长方体的宽
    return min (l[x][d], l[x][d + 1]);
}

bool check (int x, int d1, int y, int d2) { // 判断上下放置是否合法
    return (length (x, d1) <= length (y, d2)) && (width (x, d1) <= width (y, d2));
}

int main() {
    int n, m; scanf ("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf ("%d%d%d", &l[i][0], &l[i][1], &l[i][2]);
        l[i][3] = l[i][0]; l[i][4] = l[i][1];
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            for (int k = 0; k < i; ++k) {
                for (int d1 = 0; d1 <= 2; ++d1) {
                    for (int d2 = 0; d2 <= 2; ++d2) {
                        f[i][j][d1] = max (f[i][j][d1], f[k][j - 1][d2] + l[i][d1 + 2]); // 另起一堆柱子
                        if (check (i, d1, k, d2)) {
                            f[i][j][d1] = max (f[i][j][d1], f[k][j][d2] + l[i][d1 + 2]); // 放在在以前的柱子上面
                        }
                        ans = max (ans, f[i][j][d1]);
                    }
                }
            }
        }
    }
    printf ("%d", ans);
    return 0;
}
posted @   wangzhongyuan  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示