惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
有赞技术团队
有赞技术团队
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
人人都是产品经理
人人都是产品经理
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
博客园 - 【当耐特】
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
The Cloudflare Blog
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
Vercel News
Vercel News
IT之家
IT之家
MyScale Blog
MyScale Blog
博客园_首页
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
罗磊的独立博客

hsfzxjy 的博客

解决 VSCode + CMake + MSVC 编译器信息乱码的问题 使用 3090 部署 1.58bit 动态量化版 DeepSeek R1 671b 如何在 VS Code DevContainer 中配置 HTTP 代理 如何在跳板机背后的服务器上使用 VS Code Remote - Containers Cohesive Digests for Ints and Floats Rust 中的隐匿概念 —— Place(位置) 美术馆 一尺之槌,日取其半,1075日而竭 老生常谈:使用 Cloudflare 自选 IP 加速站点访问 辩义 State、Nation 与 Country 将 Base64 编码的数据快速转换为 Uint8Array 折腾 NPU·第1章 —— 搭建 Level Zero 开发环境 折腾 NPU·第0章 —— Intel NPU 概述与 Level-Zero 新增域名 monad.run CSS 中为特定字符设置不同字体 Arbitary Lifetime Transmutation via Rust Unsoundness Dijkstra 算法的延伸 Manacher 回文计数算法 硬卧 Go Fact: Zero-sized Field at the Rear of a Struct Has Non-zero Size Display *big.Rat Losslessly and Smartly in Golang 代码的仪式 Building Electron From Scratch 中式亲属称谓研究之一:构建半群 Some Notes on Kotlin Coroutines Git sparse-checkout and partial clones for Mega-Repos 辩义“封建” Diving from the CUDA Error 804 into a bug of libnvidia-container Modern Cryptography, GPG and Integration with Git(hub) Move the Root Partition of Ubuntu
UVa437 The Tower of Babylon
2014-09-23 · via hsfzxjy 的博客

链接:The Tower of Babylon 耗时:0.015s

这是刘汝佳的紫书中”DAG 中的动态规划”中的习题,我拿它用来熟悉 DAG 中的动态规划。

我们不妨进行逆向考虑:现堆上面的方块,然后考虑在下面进行叠加。这样子一来,影响决策的就只是最下面方块的尺寸了。

对于这种出现了”大套小”这样的二元关系的题,我们可以将其视为一个有向无环图:其中每个节点为一个状态,状态的转移是有固定的方向的(在此题中,状态转移为从小的方块到大的方块)。

但是这道题又不同于平常的 DAG 动态规划:若将边长视为状态的话,则要开一个巨大的数组,这是不可以接受的。因此,我们要换一种思维方式:只记录方块的序号和摆放的方式(如现将边长从小到大进行排序,然后用一个标志 k 表示当前是以第 k 小的边长作为高)。

至此,思路已经清晰了。用 $dp(i, k)$ 表示 “第 i 个方块以第 k 条边为高进行摆放” ,以下给出状态转移方程:

$$dp(i, k) = max\{dp(i, k), dp(j, k_2)\}$$

其中 $j,k_2$ 遍历所有顶面矩形比 $dp(i, k)$ 小的状态。

代码实现首次尝试了 Pascal 中的 object 类型,使其更加工整,但不可避免地损耗了一些性能。

type
Cube = object
a: array [1..3] of longint;
procedure init(x,y,z: longint);
function height(k: integer): longint;
function low(k: integer): longint;
function high(k: integer): longint;
end;

function max(x,y: longint): longint;
begin
if x>y then max := x else max := y;
end;

procedure swap(var x,y: longint);
var
t: longint;
begin
t := x;
x := y;
y := t;
end;

function Cube.height(k: integer): longint;
begin
height := self.a[k];
end;

function Cube.high(k: integer): longint;
begin
case k of
1: high := a[3];
2: high := a[3];
3: high := a[2];
end;
end;

function Cube.low(k: integer): longint;
begin
case k of
1: low := a[2];
2,3: low := a[1];
end;
end;

procedure Cube.init(x, y, z: longint);
begin
if x>y then swap(x,y);
if y>z then swap(y,z);
if x>y then swap(x,y);
a[1] := x;
a[2] := y;
a[3] := z;
end;

var
f: array [1..30, 1..3] of longint;
i,j,m,n,x,y,z: longint;
cnt: longint;
cubes: array [1..30] of Cube;

function dp(id, k: integer): longint;
var
l, h, hi: longint;
i, j: integer;
begin
if f[id, k] > 0 then
exit(f[id, k]);
l := cubes[id].low(k);
hi := cubes[id].height(k);
h := cubes[id].high(k);

f[id, k] := hi;

for i := 1 to n do
begin

for j := 1 to 3 do
begin
if not ((cubes[i].low(j) < l) and (cubes[i].high(j) < h)) then
continue;
f[id, k] := max(f[id, k], dp(i, j)+hi);
end;
end;

dp := f[id, k];
end;

begin
assign(input, 'main.in');reset(input);
assign(output, 'main.out');rewrite(output);
read(n);
cnt := 0;
while n > 0 do
begin
inc(cnt);
for i := 1 to n do
begin
read(x,y,z);
cubes[i].init(x,y,z);
end;
fillchar(f, sizeof(f), 0);

m := 0;
for i := 1 to n do
for j := 1 to 3 do
m := max(m, dp(i, j));

writeln('Case ', cnt, ': maximum height = ', m);

read(n);
end;
close(input);close(output);
end.

作者:hsfzxjy
链接:
许可:CC BY-NC-ND 4.0.
著作权归作者所有。本文不允许被用作商业用途,非商业转载请注明出处。