前言:阅读理解+剪枝+头脑风暴

Designed By FrankWkd 遵循GNU GPL2.0开源协议。

该代码可以通过T148457 生日蛋糕加强版P1731 [NOI1999] 生日蛋糕.


P1731 [NOI1999] 生日蛋糕

题目背景

数据加强版 link

题目描述

7 月 17 日是 Mr.W 的生日,ACM-THU 为此要制作一个体积为 \(N\pi\) 的 \(M\) 层生日蛋糕,每层都是一个圆柱体。

设从下往上数第 \(i\)(\(1 \leq i \leq M\))层蛋糕是半径为 \(R_i\),高度为 \(H_i\) 的圆柱。当 \(i \lt M\) 时,要求 \(R_i \gt R_{i+1}\) 且 \(H_i \gt H_{i+1}\)。

由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 \(Q\) 最小。

请编程对给出的 \(N\) 和 \(M\),找出蛋糕的制作方案(适当的 \(R_i\) 和 \(H_i\) 的值),使 \(S=\dfrac{Q}{\pi}\) 最小。

(除 \(Q\) 外,以上所有数据皆为正整数)

输入格式

第一行为一个整数 \(N\)(\(N \leq 2 \times 10^4\)),表示待制作的蛋糕的体积为 \(N\pi\)。

第二行为 \(M\)(\(M \leq 15\)),表示蛋糕的层数为 \(M\)。

输出格式

输出一个整数 \(S\),若无解,输出 \(0\)。

输入输出样例 #1

输入 #1

100
2

输出 #1

68

思路

我们先来解决 \(S=\dfrac{Q}{\pi}\),那么众所周知,\(Q=\) 所有圆环(柱)的上表面面积 \(+\) 侧面面积 ,那么我们看下图:

图源侵删

该图中的黑色部分就是我们要计算的圆环(柱)的上表面面积,我们将整合图形从上到下拍扁,就得到了一个圆柱,这个圆柱的上表面面积(也就是一个圆)就是图中黑色部分的面积。(我们设 \(R_i\) 和 \(H_i\) 为第 \(i\) 层的半径和体积)

那么第 \(1\sim i\) 层的表面积

\[Q=\sum2\pi R_{i}H_{i}+\pi R_{M}^{2}=\pi\left(\sum2R_{i}H_{i}+R_{M}^{2}\right)=\pi S
\]
\[Q=\pi S
\]

所以说 \(S\) 就是去掉 \(\pi\) 后的图形表面积。也就是 \(\sum2R_{i}H_{i}+R_{M}^{2}\)

本题就转化成了求该图形的表面积除 \(\pi\) 后的值(是整数)。

剪枝

我们设最上层的编号为 \(1\),当前 \(DFS\) 的层数为 \(u\) ,总层数为 \(m\),如下图(\(u+1\) 不一定等于 \(m\)):

优化搜索顺序

  • 我们从下向上搜索,因为下层面积大,分支少。
  • 每一层的 \(R\) 和\(H\) 从大到小枚举,因为开始的时候枚举大的数据分支就会变小,搜到数据时累计的循环次数就会比先暴搜小分支的时候小。

上下界剪枝 (接下来所有公式和等式均忽略 \(\pi\))

现在我们要确定 \(R_u\) 和 \(H_u\) 的范围。

  • 最小值:因为当前再第 \(u\) 层,第 \(1\) 层的最小值为 \(1\),第 \(2\) 层的最小值为 \(2\),以此类推,第 \(u\) 层的 \(R_u\) 和 \(H_u\) 的最小值为 \(u\)。
  • 最大值
    • 我们当前已经确定了第 \(m\sim u+1\) 层的 \(R\) 和 \(H\),我们设第 \(m\sim u+1\) 层的体积和为 \(v\) ,那第 \(1\sim u\) 层的体积和为 \(n-v\) ,那当前这一层的体积肯定小于等于还未计算所有体积,即 \(R_u^2H_u\le n-v\)。既然我们要计算 \(R_u\) 的最大值,那么我们不妨将 \(H_u\) 设为 \(1\) ,即 \(R_u^2\le n-v\),\(R_u\le \sqrt{n-v}\).
    • 根据题目内容,\(R_i >R_{i+1}\) ,因为我们是反向遍历的,所以就是 \(R_u < R_{u+1}\) 。\(H_u\) 同理.
\[R\in [u,min(R_{u+1}-1,\sqrt{n-v})]
\]
\[H\in [u,min(H_{u+1}-1,\frac{n-v}{R_{u}\times R_{u}})]
\]

可行性剪枝

我们预处理出 \(1\sim m\) 层的最小体积 \(minv[i]\) 表示第 \(1\sim i\) 层的最小体积,如果当前已经算出来的 \(u+1\sim m\) 层的体积 \(v\) 加上 \(minv[u]\) 大于总体积 \(n\) 的话,就直接 \(return\) 。

最优化剪枝

我们预处理出 \(1\sim m\) 层的最小表面积 \(mins[i]\) 表示第 \(1\sim i\) 层的最小表面积,如果当前已经算出来的 \(u+1\sim m\) 层的表面积 \(s\) 加上 \(mins[u]\) 大于当前已经搜到的合法答案的最小资 \(ans\) 的话,就直接 \(return\) 。


图源侵删

最优化剪枝 Plus (遇事不明请看上图)

\(1\sim u\) 层的最小侧面积和还可以用剩余体积 \(n-v\) 来估价。

\(1\sim u\) 层的体积和为: \(\sum_{i=1}^{{u}}{R}_{{i}}^{2}*{H}_{{i}}=n-v\),

\(1\sim u\) 层的侧面积和 \(2\sum _{{i= 1}}^{{u} }R_{{i} }* H_{{i} }\)

提公因式 \(R_u\) 得:

\[\frac 2{{R_{u}} }\sum _{{i= 1}}^{{u} }R_{{i} }* R_{{u} }* H_{{i} }
\]

因为我们是使用 \(\sum_{i=1}^{u}\) 遍历 \(1\sim u\) 中的所有数,所以肯定保证 \(i \le u\).这里我也理解了好长时间,\(\sum_{i=1}^{u}\) 等同于:for(int i = 1;i <= u;i++) ,所以在 \(for\) 里面执行的时候 \(i\) 一定 \(\le u\). 我们把原式中的的一个 \(R_u\) 换成 \(R_i\),这个式子肯定是小于等于没换的式子的。即:

\[\frac 2{{R_{u}} }\sum _{{i= 1}}^{{u} }R_{{i} }* R_{{u} }* H_{{i} }\geq \frac 2{{R_{u}} }\sum _{{i= 1}}^{{u} }R_{{i} }^{2}* H_{{i} }
\]

还记得 \(1\sim u\) 层的体积和吗?\(\sum_{i=1}^{{u}}{R}_{{i}}^{2}*{H}_{{i}}=n-v\)

将 \(\frac 2{{R_{u}} }\sum _{{i= 1}}^{{u} }R_{{i} }^{2}* H_{{i} }\) 中的 \(\sum_{i=1}^{{u}}{R}_{{i}}^{2}*{H}_{{i}}\) 替换为 \(n-v\) ,就变成了 \(\frac{2(n-v)}{R_{u}}\)。

这时你会发现 \(R_u\) 是未知的! 我们将 \(R_u\) 替换为 \(R_{u+1}\) 这时候,\(\frac{2(n-v)}{R_{u+1}}<\frac{2(n-v)}{R_{u}}\)

所以,如果 \(s+\frac{2({n}-{v})}{{R}_{u+1}}>ans\),既然小的那个式子 \(+s\) 都比当前的最优解差,那么 \(s+\frac{2(n-v)}{R_{u}}\) 一定大于当前的最优解 \(ans\),那么剪枝。

该估价不等式类似 \(A^*\)算法中的估价函数思想。(\(\frac{2(n-v)}{R_{u+1}}+s\) 类似于估价函数)

数据梳理

  • 体积: \(n=\sum_{i=1}^mR_i^2H_i\)

  • 面积:\(S=\sum2R_iH_i+R_M^2\)

  • 剪枝:

    • 1.优化搜索顺序
    • 2.上下界剪枝
      • \[R\in [u,min(R_{u+1}-1,\sqrt{n-v})]
        \]
      • \[H\in [u,min(H_{u+1}-1,\frac{n-v}{R_{u}\times R_{u}})]
        \]
    • 3.可行性剪枝(体积和越界)
      • \[v+minv[u] > n
        \]
    • 4.最优性剪枝(面积和更差)
      • \[s+mins[u]>ans
        \]
    • 最优性剪枝(面积和更差)
      • \[s+\frac{2(n-v)}{R_{u+1}} > ans
        \]
  • 为什么要保留两个面积和更差的剪枝?

  • 【Powered By Doubao】

  • 第4、5个剪枝虽都围绕表面积优化,但二者存在本质差异与互补性,具体原因如下:

1. 原理不同,覆盖不同逻辑分支

  • 第4个剪枝:基于预处理的固定值 mins[u](前 u 层最小侧面积和,每层取半径、高度为层号时的侧面积累加)。它是一种“静态通用下限”,只要当前表面积 s + mins[u] > ans,就说明即使剩余层取理论最小侧面积,总表面积仍超最优解,直接剪枝。
  • 第5个剪枝:通过剩余体积 n - v 动态推导侧面积下限,结合半径关系(如 R_{u+1})。它是“动态实时下限”,利用剩余体积的分配逻辑,推导出侧面积必然超标的情况,剪枝与剩余体积强相关的无效分支。

2. 场景互补,提升剪枝全面性

  • 第4个剪枝:处理“仅侧面积部分就已超最优解”的通用场景,不依赖剩余体积的具体数值,通过预处理数组快速判断。
  • 第5个剪枝:处理“因剩余体积分配导致侧面积超标”的特殊场景,利用体积与半径的数学关系,覆盖第4个剪枝未涉及的逻辑。

3. 效率互补,减少无效计算

  • 单独使用第4个剪枝,无法利用剩余体积的动态信息,可能遗漏与体积相关的无效分支;单独使用第5个剪枝,缺少对通用最小侧面积的快速判断。
  • 两者结合,从“固定预处理下限”和“动态体积推导下限”两个维度,更全面地过滤无效搜索路径,大幅减少DFS的计算量,提升算法效率。

代码

#include <bits/stdc++.h>
using namespace std;
const int Inf = 1e9;
int minv[30],mins[20],n,m;
int ans = Inf;
void dfs(int u,int r,int h,int v,int s){
if(u == 0){
if(s < ans and v == n) ans = s;
return ;
}
if(v+minv[u] > n) return;
if(s+mins[u]>=ans) return;
if(s+2*(n-v)/r >= ans) return;
for(int i = min(r-1,(int)sqrt(n-v));i >= u;i--){
for(int j = min(h-1,(n-v)/(i*i));j >= u;j--){
dfs(u-1,i,j,v+i*i*j,s+2*i*j+(u==m?i*i:0));
}
}
}
int main(){
cin>>n>>m;
for(int i = 1;i <= m;i++){
mins[i] = mins[i-1]+2*i*i;
minv[i] = minv[i-1]+i*i*i;
}
dfs(m,Inf,Inf,0,0);//从下向上遍历 if(ans == Inf) puts("0");
else cout<<ans<<endl;
}

注释版本:

【题解】洛谷P731[NOI1999] 生日蛋糕+数据加强版的更多相关文章

  1. 洛谷P1120 小木棍 [数据加强版](搜索)

    洛谷P1120 小木棍 [数据加强版] 搜索+剪枝 [剪枝操作]:若某组拼接不成立,且此时 已拼接的长度为0 或 当前已拼接的长度与刚才枚举的长度之和为最终枚举的答案时,则可直接跳出循环.因为此时继续 ...

  2. 【题解】洛谷P1731 [NOI1999] 生日蛋糕(搜索+剪枝)

    洛谷P1731:https://www.luogu.org/problemnew/show/P1731 思路 三重剪枝 当前表面积+下一层表面积如果超过最优值就退出 当前体积+下一层体积如果超过总体积 ...

  3. 洛谷 P1731 [NOI1999]生日蛋糕

    P1731 [NOI1999]生日蛋糕 题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M ...

  4. 洛谷——P1731 [NOI1999]生日蛋糕

    P1731 [NOI1999]生日蛋糕 搜索+剪枝 常见的剪枝: 若当前状态+后面所要搜索的最差的状态$>$或是$<$最后的状态,就返回 预处理最差的状态 #include<iost ...

  5. C++ 洛谷 P1731 [NOI1999]生日蛋糕

    P1731 [NOI1999]生日蛋糕 一本通上也有. 这TM是一道极其简单的深搜剪枝(DP当然可以的了,这里我只讲深搜). 首先圆柱公式:(有点数学基础都知道) V=πR2H S侧=π2RH S底= ...

  6. 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕

    题目传送门(洛谷)  OR 题目传送门(POJ) 解题思路: 一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝. 1.如果当前状态答案已经比我们以前某个状态 ...

  7. 洛谷 P1731 [NOI1999]生日蛋糕 题解

    每日一题 day53 打卡 Analysis 观察一个蛋糕的俯视图,上表面的面积其实就是最下面那一层的底面积,所以在第一次搜索的时候加入这个底面积,之后就只用考虑侧面积就好啦. 就是每次枚举r和h,如 ...

  8. POJ1190 洛谷P1731 NOI1999 生日蛋糕

    生日蛋糕(蛋糕是谁?) Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20272   Accepted: 7219 Desc ...

  9. [洛谷P1731][NOI1999]生日蛋糕(dfs)(剪枝)

    典型的深搜+剪枝策略 我们采用可行性剪枝.上下界剪枝.优化搜索顺序剪枝.最优性剪枝的方面来帮助我们进行剪枝. 也许有人还不知道剪枝,那我就弱弱地为大家补习一下吧qwq: .优化搜索顺序: 在一些搜索问 ...

  10. 洛谷P1731 [NOI1999]生日蛋糕(爆搜)

    题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri, 高度为Hi的圆柱 ...

随机推荐

  1. java中的ArrayBlockingQueue

    ArrayBlockingQueue ArrayBlockingQueue 是 Java 并发包 (java.util.concurrent) 中的一个线程安全的阻塞队列实现. 它基于数组实现,容量固 ...

  2. Protobuf生成文件报错

    Mac下protobuf生成文件报错问题解决办法,windows下就不会这么麻烦了,如果linux下出现类似报错信息按照下面的解决逻辑依然适用. 1.由--go_out引发的报错 1.报错信息: us ...

  3. Clickhouse常见异常

    一.异常 1)DB::Exception: Nested type Array(String) cannot be inside Nullable type (version 20.4.6.53 (o ...

  4. Math.atan2求角度解析

    我们求角度的时候, 第一反应应该是Math.tan(x/y)就得到角度了 但是这样求的是和y轴的夹角,如果以y轴正方向为0度,顺时针为正,则第三象限和第一象限的tan值一致,需要判断x,y和0的关系, ...

  5. macbookpro m3本地部署DeepSeek模型

    macbookpro m3有着十分强大的性能.在deepseek如火如荼的当下,可以尝试在本地部署并使用.还可以将自己的文档作为语料喂给deepseek,使其能成为自己专属的AI助手. 本文介绍使用o ...

  6. 异地组网工具 Radmin_LAN:将远程计算机连接到单一本地网络

    Radmin LAN是一款使用简单的免费软件产品,用于创建虚拟本地网络.该程序允许用户安全地连接位于防火墙后的计算机.为流量提供一个安全通道.可靠的端到端加密(256位AES)确保您的连接安全. Ra ...

  7. SIT、UAT以及PROD环境的区别

    题记部分 一.SIT环境   SIT(System Integration Testing)环境主要用于系统集成测试,旨在验证系统中不通模块之间的集成和交互是否正常工作.这个环境通常用于开发团队内部进 ...

  8. Linux - 配置IP&主机名的快捷操作

    nmtui 执行以下命令可以进入一个可视化界面,进行IP的可视化配置.以及网络服务的重启(注意,这个重启是停止然后启动, 如果使用xshell进行操作会失去ssh连接,直连服务器时可这直接操作).主机 ...

  9. SSM:Spring整合Mybatis时,连接池和SQLSessionFactory的联系!

  10. 浅谈Tox之一

    本文分享自天翼云开发者社区<浅谈Tox之一>,作者:Moonriver What is tox? tox是通用的virtualenv管理和测试命令行工具,可用于: 使用不同的Python版 ...