POJ-1190生日蛋糕(详细题解)深度优先搜索

2024-01-08 12:30

本文主要是介绍POJ-1190生日蛋糕(详细题解)深度优先搜索,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

POJ-1190

题目描述

7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。
当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ,请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。(除Q外,以上所有数据皆为正整数)

输入

有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。

输出

仅一行,是一个正整数S(若无解则S = 0)。

例子输入

100
2

例子输出

68

提示

圆柱公式
体积V = πR 2H
侧面积A’ = 2πRH
底面积A = πR 2

在这里插入图片描述

蛋糕的体积: V = N π = π R 1 2 H 1 + π R 2 2 H 2 + . . . + π R n 2 H n V=Nπ=πR_1^2H_1+πR_2^2H_2+...+πR_n^2H_n V=Nπ=πR12H1+πR22H2+...+πRn2Hn

: N = R 1 2 H 1 + R 2 2 H 2 + . . . + R n 2 H n N=R_1^2H_1+R_2^2H_2+...+R_n^2H_n N=R12H1+R22H2+...+Rn2Hn
其中 ( R 1 > R 2 > R 3 > . . . > R n 且 H 1 > H 2 > H 3 > . . . > H n ) (R_1>R_2>R_3>...>R_n且H_1>H_2>H_3>...>H_n) (R1>R2>R3>...>RnH1>H2>H3>...>Hn)

蛋糕的表面积: Q = S π = π R 1 2 + 2 π R 1 H 1 + 2 π R 2 H 2 + . . . + 2 π R n H n Q=Sπ=πR_1^2+2πR_1H_1+2πR_2H_2+...+2πR_nH_n Q=Sπ=πR12+2πR1H1+2πR2H2+...+2πRnHn

: S = R 1 2 + 2 R 1 H 1 + 2 R 2 H 2 + . . . + 2 R n H n S=R_1^2+2R_1H_1+2R_2H_2+...+2R_nH_n S=R12+2R1H1+2R2H2+...+2RnHn
其中 ( R 1 > R 2 > R 3 > . . . > R n 且 H 1 > H 2 > H 3 > . . . > H n ) (R_1>R_2>R_3>...>R_n且H_1>H_2>H_3>...>H_n) (R1>R2>R3>...>RnH1>H2>H3>...>Hn)

解题思路:
深度优先搜索:
从底层开始搜索,当底层半径和高度确定时,则搭建剩余层蛋糕所需的最小体积(min_v)和最大体积(max_v)就可以确定了,因此,每当我们搭建完一层时,应该比较一下max_v,min_v和剩余可用体积 V − V i V-V_i VVi)此时有三种情况:
第一种情况、

如果搭建完剩余层所需的最小体积(min_v)比剩余可用体积( V − V i , 其 中 V i V-V_i,其中V_i VVi,Vi表示搭建底层蛋糕已经使用的体积)还要大,则说明题目所固定的体积不够用,此时应该减小底层固定的半径 R i 和 H i R_i和H_i RiHi,直到它们满足第三种情况

第二种情况、

如果搭建完剩余蛋糕层所需最大体积(max_v)比剩余可用体积( V − V i V-V_i VVi)还要小的话,则说用题目所固定的体积用不完,此时应该增大底层固定的半径 R i 和 H i R_i和H_i RiHi,直到它们满足第三种情况

第三种情况、

如果搭建完剩余蛋糕层所需的最小体积(min_v)和最大体积(max_v)满足(min_v < = ( V − V i ) < = <=(V-V_i)<= <=(VVi)<=max_v),则说明从第一层至当前层所搭建的蛋糕层符合题目要求,继续向上层搭建

由题目给定的数值,我们无需考虑π值,则上述的体积可用直接用整数值表示,比如:
当前已用体积 V i = R 1 2 H 1 + R 2 2 H 2 + . . . R i 2 H i V_i=R_1^2H_1+R_2^2H_2+...R_i^2H_i Vi=R12H1+R22H2+...Ri2Hi
当前剩余体积 V − V i = N − ( R 1 2 H 1 + R 2 2 H 2 + . . . R i 2 H i ) = R i + 1 2 H i + 1 + R i + 2 2 H i + 2 + . . . R n 2 H n V-V_i=N-(R_1^2H_1+R_2^2H_2+...R_i^2H_i)=R_{i+1}^2H_{i+1}+R_{i+2}^2H_{i+2}+...R_n^2H_n VVi=N(R12H1+R22H2+...Ri2Hi)=Ri+12Hi+1+Ri+22Hi+2+...Rn2Hn

1.首先确定第一层半径R和高度H的最大值最小值:
总共有M层蛋糕,且每一层的半径和高度都是整数 ( R 1 > R 2 > R 3 > . . . > R n 且 H 1 > H 2 > H 3 > . . . > H n ) (R_1>R_2>R_3>...>R_n且H_1>H_2>H_3>...>H_n) (R1>R2>R3>...>RnH1>H2>H3>...>Hn),则最高层的半径和高度至少为1,由此可以确定第一层的半径和高度皆不小于M;

N = R 1 2 H 1 + R 2 2 H 2 + . . . + R n 2 H n N=R_1^2H_1+R_2^2H_2+...+R_n^2H_n N=R12H1+R22H2+...+Rn2Hn 得:

M = 1 , H 1 = 1 M=1,H_1=1 M=1,H1=1时, R 1 R_1 R1最大,且此时 R 1 = N R_1=\sqrt{N} R1=N ,所以 R 1 R_1 R1的取值范围为[M, N \sqrt{N} N ] 当 R 1 R_1 R1的值确定时, H 1 = N R 1 2 H_1=\frac{N}{R_1^2} H1=R12N,同时 H 1 > = M H_1>=M H1>=M

2.依次确定上一层的半径和高的范围

M − i + 1 < = R i < = R i − 1 − 1 ; M-i+1<=R_i<=R_{i-1}-1; Mi+1<=Ri<=Ri11;
M − i + 1 < = H i < = H i − 1 − 1 ; M-i+1<=H_i<=H_{i-1}-1; Mi+1<=Hi<=Hi11;

3.根据已确定的半径和高度判断是否有可能满足题目要求
即分析上述的三种情况,max_v 和 min_v 和 V 三者之间的关系,若不满足则不断改变当前 R 和 H 的值,直到满足为止

4.确定最小的表面积
1.将第一次符合题目要求1的表面积(min_s)记录,然后在遍历其它情况,如果在深度优先搜索的过程中发现已搭建的蛋糕表面积大于之前记录的最小表面积(min_s)则这种情况无需继续遍历,此时应该改变R和H的值,再进行另一种情况的遍历。
2.如果确立一种新的情况则判断当前蛋糕变面积和之前确立的最小表面积的值进行比较,如果当前 S < S< S<min_s,则交换它们的值,(即更新最小表面积)

5.当枚举完所有情况时返回最小表面积的值

代码如下(C++):

//time:563MS
#include<iostream>
#include<cmath>
#include<string>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int N, M;//分别表示体积和层数
int min_s = 0x7fffffff;//初始化为最大值
inline int min_v(int m)//此函数用于计算搭建剩余蛋糕层所需的最小体积
{int v = 0;//将剩余层的半径设为最小值,即从最高层到当前的上一层分别为1,2,3,4...M-m//每一层高度H取值和R一样,才能保证V最小;for (int R = M - m; R >= 1; R--){int H = R;v += R * R * H;}return v;
}inline int max_v(int r, int h, int m)//此函数用于计算搭建剩余蛋糕层所需的最大体积
{int v = 0;//由于上层半径和高度必须必下层半径和高度小,所以每一层半径和高度的最大取值应是其下层的半径或高度减一for (int R = r, H = h; m <= M; R--, H--,m++){//只有将剩余的每一层的半径和高度设为最大值,才能保证求得的V最大v += R * R * H;}return v;
}
inline void dfs(int r, int h, int m, int s, int v)//深度优先搜索,其中m表示当前在搭建的层数,s表示已经搭建的蛋糕层的表面积,v表示已经使用的体积
{if (m == M && N == v && s < min_s){min_s = s;//更新最小表面积的数值return;}//如果预估蛋糕的最小面积大于前面所确立最小面积,则无需继续深索if (r == 0 || s + 2 * (N - v) / r > min_s)return;//如果预估搭建剩余层所需的最小体积大于剩余可用体积,则说明规定的体积不够用,返回if (min_v(m) > N - v)//第一种情况return;//如果预估搭建剩余层所需的最大体积小于剩余可用体积,则说明无法达到规定的体积,返回if (max_v(r, h, m) < N - v)//第二种情况return;//如果上述条件均不满足,则说明满足第三种情况,则继续深索for (int R = r - 1; R >= M - m; R--)//枚举下一层蛋糕的半径for (int H = h - 1; H >= M - m; H--)//枚举下一层蛋糕的高{//注意,此时的最小值不是M-m+1,因为对应的是下一层的半径和高,所以最小值应该是M-mdfs(R, H, m + 1, s + 2 * R * H, v + R * R * H);//深搜下一层}
}
int main()
{scanf_s("%d%d", &N, &M);for (int r1 = M; r1 * r1 <= N; r1++)//枚举所有可能的半径和高度for (int h1 = N / (r1 * r1); h1 >= M; h1--){int s = r1 * r1 + r1 * h1 * 2;//表示第一层的表面积int v = r1 * r1 * h1;//表示第一层使用的体积dfs(r1, h1, 1, s, v);//固定了第一层的半径和高度之后,往上层去探索}if (min_s == 0x7fffffff)cout << 0 << endl;elsecout << min_s << endl;return 0;
}

如果此文能够帮助到您,烦请点赞收藏,嘻嘻!
以上内容如有不足,请谅解并欢迎指出,最后附上本人微信公众号,欢迎大家一起讨论学习,更多精彩内容请关注公众号:“艺千秋录”,欢迎留言共同进步;
在这里插入图片描述


  1. 符合题目要求的意思就是成功搭建了层数为M且体积为Nπ的蛋糕。 ↩︎

这篇关于POJ-1190生日蛋糕(详细题解)深度优先搜索的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/583453

相关文章

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

C++ vector的常见用法超详细讲解

《C++vector的常见用法超详细讲解》:本文主要介绍C++vector的常见用法,包括C++中vector容器的定义、初始化方法、访问元素、常用函数及其时间复杂度,通过代码介绍的非常详细,... 目录1、vector的定义2、vector常用初始化方法1、使编程用花括号直接赋值2、使用圆括号赋值3、ve

python连接本地SQL server详细图文教程

《python连接本地SQLserver详细图文教程》在数据分析领域,经常需要从数据库中获取数据进行分析和处理,下面:本文主要介绍python连接本地SQLserver的相关资料,文中通过代码... 目录一.设置本地账号1.新建用户2.开启双重验证3,开启TCP/IP本地服务二js.python连接实例1.

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

Python基础文件操作方法超详细讲解(详解版)

《Python基础文件操作方法超详细讲解(详解版)》文件就是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位,文件的核心操作就是读和写,:本文主要介绍Python基础文件操作方法超详细讲解的相... 目录一、文件操作1. 文件打开与关闭1.1 打开文件1.2 关闭文件2. 访问模式及说明二、文件读写1.

Ubuntu中远程连接Mysql数据库的详细图文教程

《Ubuntu中远程连接Mysql数据库的详细图文教程》Ubuntu是一个以桌面应用为主的Linux发行版操作系统,这篇文章主要为大家详细介绍了Ubuntu中远程连接Mysql数据库的详细图文教程,有... 目录1、版本2、检查有没有mysql2.1 查询是否安装了Mysql包2.2 查看Mysql版本2.