(DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕

题目链接

点此快速前往

题目总分析

就和我说的一样,这道题就是DFS加剪枝,非常好的一道题

我起初看到这个题我根本不知道怎么dfs才是正确的, 感觉变量有这么多不确定的,每一层的半径,每一层的高度,而且这之间的联系在刚看到这个题的我看来十分的小,应该是我太菜了导致的

深入往下看,你就发现实际上这道题已经告诉了你每一层的限制了,并不是完全无从下手,至少你知道这一层的半径和高度一定小于等于它底下那一层的半径和高度-1,所以我们不难想象出dfs的做法:最下面那一层的半径最大值是假设只有一层,n-1就是它起初的最大值,那么最小值就是总共的层数,,因为每一层都要至少要少1,所以最大的那一层半径和高度肯定就最小值就是层数

为什么不遍历高度而是半径呢?

你稍微列一下式子你就会发现,实际上半径对总面积的影响程度要高于高度的,所以想要最小,一定是从半径入手。

总体积 n = ∑ i = 1 m R i ∗ H i 总体积 n = \sum_{i = 1}^{m} R_i * H_i 总体积n=i=1mRiHi

总面积 m = R 0 2 + ∑ i = 1 m R i 2 ∗ H i 总面积 m = R_0^2 + \sum_{i=1}^{m} R_i^2 * H_i 总面积m=R02+i=1mRi2Hi

为什么总面积前面有个 R 0 2 R_0^2 R02

简单想想,虽然是每个圆柱都被另一个比它小的圆柱盖住了一个圆的面积,但是你从这个蛋糕的最上面去看,就不难发现,最上面的面积和其实就是最底层圆柱的顶面面积。

看到这可能已经想要去写了,不过先停一下
这道题dfs搜索只是第一步,而更重要的是剪枝,由于处理数据的量也是非常大的,如果不进行一些优化就没办法顺利进行

首先既然我们知道每一层最小的半径和高,那么我们就不难算出来到每一层为止,最小的体积和最小的面积分别是多少

有了上述的信息之后,我们在准备遍历之前可以先判断一下

  1. 如果此时此刻接下来几层的最小面积加上此时的面积已经大于等于当前的最优解你,那就没有必要去遍历了。
  2. 同样,接下里几层的最小体积加上此时的体积已经大于要求的总体积n,那么也没必要去遍历了
  3. 这个是比较难想的,我们是从最下层遍历到最上层的,也就是说假设此时此刻遍历的层数半径为r,包括这一层之前的总体积为v以及总面积是s , 总共的蛋糕体积是n,那么如果 2 ∗ ( n − v ) / r > 此时的最优解 2 * (n - v) / r > 此时的最优解 2(nv)/r>此时的最优解,同样也没有遍历下去的必要了

前两个好理解,第三个是什么东西啊?
很好我开始看到的时候也非常困惑,接下来推导一下你就懂了

从m开始now是已经搭建好的层数了,now-1就是接下来之后的层

接下里的面积应该是 ∑ i = 1 n o w − 1 R i 2 ∗ H i 接下里的面积应该是\sum_{i = 1}^{now - 1} R_i^2 * H_i 接下里的面积应该是i=1now1Ri2Hi
看一下我第三条公式,你可以清楚的发现, R i R_i Ri全部都小于当前这一层的 r 所以,接下里的面积必然比 2 ∗ ( n − v ) / r 2 * (n - v) / r 2(nv)/r大,如果这个面积都大于等于最优解了,那么就不需要遍历了

接下来就是代码实现了,基本思路已经写完,代码中有不理解的部分可以评论区提问一下或者私信。

总代码

#include<bits/stdc++.h>
using namespace std;
const int N = 25 , INF = 0x3f3f3f3f;
int n,m;
int ans = INF;
int Mins[N] , Minv[N];
void dfs(int now,int r,int h,int s,int v)
{int MH = h;if(now == 0){if(v == n){ans = min(ans, s);}return ;}if(Mins[now-1] + s >= ans) return;if(Minv[now-1] + v > n) return;if(2 * (n - v) / r + s >= ans) return;for(int i=r-1;i>=now;i--){if(now == m) s = i * i;MH = min(h-1 , (n - Minv[now-1] - v) / i / i);for(int j = MH ; j >= now ; j--){dfs(now-1 , i , j , s + 2 * i * j , v + i * i * j);}}
}int main()
{cin >> n >> m;for(int i=1;i<=m;i++){Mins[i] = Mins[i-1] + i * i * 2;Minv[i] = Minv[i-1] + i * i * i;}dfs(m,n,n,0,0);if(ans == INF) cout << 0 << '\n';else cout << ans << '\n';return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tauri应用实现一键快速更新版本

tauri应用实现一键快速更新版本 创建一个项目 pnpm create tauri-app根据配置选择就可以 pnpm tauri dev启动项目 ##更新配置 打包配置在src-tauri/tauri.conf.json 修改打包命令 "bundle": {"active": true,"targets": "all",&qu…

概率论基础概念

随机试验 随机试验&#xff08;Random Experiment&#xff09;是在相同条件下对某随机现象进行的大量重复观测。这种试验具有以下特点&#xff1a; 在试验前不能断定其将发生什么结果&#xff0c;但可明确指出或说明试验的全部可能结果是什么。 在相同的条件下试验可大量地重…

XR虚拟拍摄:短剧制作的新宠

XR虚拟拍摄&#xff1a;短剧制作的新宠 随着数字技术的快速发展&#xff0c;短剧拍摄领域正在经历一场革命性的变革。XR&#xff08;扩展现实&#xff09;技术的兴起&#xff0c;为短剧制作带来了前所未有的机遇与挑战。近年来&#xff0c;越来越多的短剧制作团队开始采用XR虚拟…

谷粒商城——Redisson看门狗

可重入锁&#xff1a; 看门狗机制&#xff1a;(lock.lock()不设置过期时间就会自动触发 看门狗机制) 如果一个线程已经上锁后&#xff0c;在运行的过程中中断导致未释放锁从而导致其他线程无法进行&#xff0c;为此需要为每个锁设置自动过期时间。但是如果线程运行时间较长&am…

Learn OpenGL 25 法线贴图

为什么要引入法线贴图 我们的场景中已经充满了多边形物体&#xff0c;其中每个都可能由成百上千平坦的三角形组成。我们以向三角形上附加纹理的方式来增加额外细节&#xff0c;提升真实感&#xff0c;隐藏多边形几何体是由无数三角形组成的事实。纹理确有助益&#xff0c;然而…

Linux进程地址空间详解

文章目录 前言一、程序地址空间二、感受虚拟地址的存在三、进程地址空间四、程序从磁盘加载到内存的过程4.1 物理地址和虚拟地址的区别 五、写时拷贝5.1 解释fork()函数有两个返回值 前言 我们在学习C/C的时候用到的地址是什么地址呢&#xff1f;虚拟地址&#xff1f;物理地址&…

【无人机综合考试题】

1.请选择出哪一个功能选项&#xff0c;在手动遥控飞行时&#xff0c;可以改变各通道的操作灵敏度? 行程比例在手动遥控飞行时&#xff0c;可以改变各通道的操作灵敏度 用于起降的遥控器中 THR、ELE 通道分别控制多旋翼无人机的什么运动? AIL(左、右移动)RUD(左、右水平旋转…

Java基础【上】韩顺平(反射、类加载、final接口、抽象类、内部类)

涵盖知识点&#xff1a;反射、类加载、单例模式、final、抽象类、接口、内部类&#xff08;局部内部类、匿名内部类、成员内部类、静态内部类&#xff09; P711 反射机制原理 创建如下目录结构&#xff0c;在模块下创建src文件夹&#xff0c;文件夹要设置为Sources文件夹&…

红桃写作方便吗 #学习方法#微信#微信

红桃写作是一个非常好用的论文写作工具&#xff0c;它不仅方便快捷&#xff0c;而且非常靠谱&#xff0c;能够帮助用户轻松完成论文写作任务。不论是学生还是专业人士&#xff0c;都可以通过红桃写作轻松地完成论文的写作工作&#xff0c;大大提高工作效率。 首先&#xff0c;红…

多人协作的思考

有时候可能会有多人协作的需求&#xff0c;多人协作有很多实现方式 可以多人改&#xff0c;但是同时只有一人能改。这种不算纯粹的多人协作&#xff0c;偏权限控制。 飞书文档类的多人协作&#xff0c;大家都在同一个数据载体上修改。 git式的多人协作&#xff0c;没人都有一…

flutter->Scaffold左侧/右侧侧边栏和UserAccountsDrawerHeader的使用

//appBar的 leading/actions 和 Scaffold的drawer/endDrawer 冲突只能存在一个 import package:flutter/material.dart;void main() {runApp(MyApp()); }class MyApp extends StatelessWidget {const MyApp({super.key});overrideWidget build(BuildContext context) {retur…

【docker常用命令】

1. 什么是docker Docker 是一种开源的容器化平台&#xff0c;用于开发、交付和运行应用程序。它允许开发人员将应用程序及其依赖项&#xff08;如库、环境变量、配置文件等&#xff09;打包到一个被称为容器的标准化单元中。这个容器包含了一切应用程序需要运行的所有内容&…

Python编程—Ajax数据爬取

Python编程—Ajax数据爬取 ​ 在浏览器中可以看到正常显示的页面数据&#xff0c;而使用requests得到的结果中并没有这些数据。这是因为requests获取的都是原始HTML文档&#xff0c;而浏览器中的页面是JavaScript处理数据后生成的结果&#xff0c;这些数据有多种来源&#xff…

使用 Suno 创作歌曲

Suno 是一款基于人工智能的音乐创作工具&#xff0c;可以帮助您轻松创作原创歌曲。 它可以根据您的歌词生成旋律、和弦和伴奏&#xff0c;并提供多种风格和情绪供您选择。 在本文中&#xff0c;我们将介绍如何使用 Suno 创作歌曲。 我们将使用以下步骤&#xff1a; 选择客制化…

蓝桥杯每日一题:扫雷

题目来源&#xff1a;第十三届蓝桥杯软件赛省赛 B组 在一个 n n n 行 m m m 列 的方格图中有些位置有地雷, 另外一些位置为空 请为每个空位置标一个整数, 表示周围八个相邻的方格中有多少个地雷 输入 : 输入的第一行包含两个整数 n n n , m m m 第 2 行 到 第 n 1 n 1 n…

windows 系统下(nacos1.x) nacos-1.1.3 链接数据库 mysql8.0 出错分析

** windows 系统下&#xff08;nacos1.x&#xff09; nacos-1.1.3 链接数据库 mysql8.0 出错分析 ** 1、首先以下方法亲测无效&#xff1a; 1&#xff09;需要在数据库 URL 链接配置信息中 添加 allowPublicKeyRetrievaltrue 无效 db.url.0**&allowPublicKeyRetrievalt…

算法-最短路径

图的最短路径问题是一个经典的计算机科学和运筹学问题&#xff0c;旨在找到图中两个顶点之间的最短路径。这种问题在多种场景中都有应用&#xff0c;如网络路由、地图导航等。 解决图的最短路径问题有多种算法&#xff0c;其中最著名的包括&#xff1a; 1.迪杰斯特拉算法 (1).…

NIO详解

前期处理 对应的思维导图地址: https://www.processon.com/view/link/62247e810e3e74108ca1b5d7 对应的 Github地址: https://github.com/yuejianli/NIO 依赖 全局 pom.xml 依赖 <dependencies><dependency\><groupId\>junit</groupId\><artif…

AWTK T9 输入法实现原理

1. T9 输入法的中文字典数据 网上可以找到 T9 输入法的中文字典数据&#xff0c;但是通常有两个问题&#xff1a; 采用 GPL 协议&#xff0c;不太适合加入 AWTK。 只支持单个汉字的输入&#xff0c;不支持词组的输入。 经过考虑之后&#xff0c;决定自己生成 T9 输入法的中…

Mamba复现与代码解读

文章目录 环境配置demo推理源码解析参数解读Mamba块&#xff08;Mamba Block&#xff09;状态空间模型(SSM)选择性扫描算法&#xff08;selective_scan&#xff09;前向传播&#xff08;forward&#xff09; 均方根归一化 &#xff08;RMSNorm&#xff09;残差块&#xff08;Re…