生日蛋糕(dfs+剪枝)
生日蛋糕
题目:
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外,以上所有数据皆为正整数)
Input
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
Output
仅一行,是一个正整数S(若无解则S = 0)。
Sample Input
100
2
Sample Output
68
Hint
圆柱公式
体积V = πR 2H
侧面积A' = 2πRH
底面积A = πR 2
思路:
很容易就可以知道是按照层数进行dfs。当满足层数条件以及体积条件时,找到最小的答案就可以输出了。只是为什么想把这题目写出来呢?因为这题目对时间的要求看似宽松,实则让人想吐血。写出来的dfs需要大量地剪枝,尤其是hnust的oj上对剪枝的要求简直是……太严格了。主要是需要剪枝的有三大类:
1) n+minv[m-1]>N 当前已经计算出来的蛋糕的体积,加上剩下的层数中可能制造出的最少的蛋糕的体积的结果如果大于n,剪掉。
2) sum+mins[m-1]>ans 当前已经计算出来的蛋糕的表面积,加上剩下层数中可能制造出的最少的蛋糕的表面积的结果如果大于之前计算出来的结果(ans)时,剪掉。
3) sum+2*(N-n)/r>=ans 数学公式推导:n-sumv既所剩体积记作dv 还需要的表面积为s
s=2*ri*hi+2*r(i-1)*h(i-1)+...
>=2*ri*hi*ri/r+2*r(i-1)*h(i-1)*r(i-1)/r+...
=2*dv/r(i从M-1取,r为当前半径
ri/r<1)
所以得到还需要的最小表面积s=2*(n-sum)/r,如果最小的s和已经搜索过的表面积sum依然比ans大
就不用继续搜索了
如果还是时间超限的话(例如hnust里提供的数据)就需要第四次剪枝了。
4)当前计算出来的体积,加上可能的最大的蛋糕体积的结果小于n,剪掉。这个是参考了大佬的思路,就不贴出来了,都找得到
AC代码:
#include<bits/stdc++.h> using namespace std;
int h,r,N,M,mins[],minv[];
const int inf=<<;
int ans=inf;
int sum=;
void dfs(int r,int h,int n,int m,int sum)
{
if(m==)
{
if(n==N&&sum<ans)
{
ans=sum;//cout<<r<<" "<<h<<endl;
}
return;
}
if(n+minv[m-]>N||sum+mins[m-]>ans||sum+*(N-n)/r>=ans)
return;
for(int i=r-; i>=m; i--)
{
int jl=i*i;
if(m==M)
sum=jl;
int maxh=((N-n-minv[m-])/(i*i)<h-)? (N-n-minv[m-])/(i*i):h-;
for(int j=maxh; j>=m; j--)
{
dfs(i,j,n+jl*j,m-,sum+*i*j);
}
}
}
int main()
{
minv[]=;
mins[]=;
for(int i=; i<=; i++) //从顶层向下计算出最小体积和表面积的可能值
{
//从顶层(即第一层)到第i层的最小体积minv[i]成立时第j层的半径和高度都是j
minv[i]=minv[i-]+i*i*i;
mins[i]=mins[i-]+*i*i;
}
while(scanf("%d %d",&N,&M)==)
{
ans=inf;
int rmax=(int)sqrt((double)N); //rmax初始半径 底层半径 最大值为sqrt(n)
int hmax=N; //hmax初始高度 高度最大为 n
dfs(rmax,hmax,,M,);
if(ans==inf)
cout<<<<endl;
else
cout<<ans<<endl;
}
return ;
}
生日蛋糕(dfs+剪枝)的更多相关文章
- POJ1190生日蛋糕[DFS 剪枝]
生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18236 Accepted: 6497 Description ...
- [洛谷P1731][NOI1999]生日蛋糕(dfs)(剪枝)
典型的深搜+剪枝策略 我们采用可行性剪枝.上下界剪枝.优化搜索顺序剪枝.最优性剪枝的方面来帮助我们进行剪枝. 也许有人还不知道剪枝,那我就弱弱地为大家补习一下吧qwq: .优化搜索顺序: 在一些搜索问 ...
- 洛谷P1731生日蛋糕(dfs+剪枝)
P1731 生日蛋糕 题目背景 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层 生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1<=i<=M)层蛋糕是半径为R ...
- POJ - 1190 生日蛋糕 dfs+剪枝
思路:说一下最重要的剪枝,如果当前已经使用了v的体积,为了让剩下的表面积最小,最好的办法就是让R尽量大,因为V = πR 2H,A' = 2πRH,A' = V / R * 2 ,最大的R一定是取当前 ...
- 生日蛋糕 (poj1190) (dfs剪枝)
[题目描述] 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为 ...
- *HDU1455 DFS剪枝
Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- POJ 3009 DFS+剪枝
POJ3009 DFS+剪枝 原题: Curling 2.0 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16280 Acce ...
- poj 1724:ROADS(DFS + 剪枝)
ROADS Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10777 Accepted: 3961 Descriptio ...
- DFS(剪枝) POJ 1011 Sticks
题目传送门 /* 题意:若干小木棍,是由多条相同长度的长木棍分割而成,问最小的原来长木棍的长度: DFS剪枝:剪枝搜索的好题!TLE好几次,终于剪枝完全! 剪枝主要在4和5:4 相同长度的木棍不再搜索 ...
- DFS+剪枝 HDOJ 5323 Solve this interesting problem
题目传送门 /* 题意:告诉一个区间[L,R],问根节点的n是多少 DFS+剪枝:父亲节点有四种情况:[l, r + len],[l, r + len - 1],[l - len, r],[l - l ...
随机推荐
- [BZOJ 2989]数列(二进制分组+主席树)
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[ ...
- osi七层协议 Open System Interconnection
一, 操作系统基础 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必 ...
- MySQL5.7 慢查询+DDL操作堵塞查询
数据库版本: mysql> select @@version; +------------+ | @@version | +------------+ | 5.7.26-log | +----- ...
- PHP Web Server 实例
通过WebService,我们可以调用部署在其它地方的程序,而不用关心被调用的程序是在什么平台用什么语言编写的.这里我们使用php调用. 在php4时代调用WebService大部分使用的nusoap ...
- 可视化操作,实现横向柱形echart图 无边框
图片的实现: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <ti ...
- JDK 8 中Stream流中的去重的方法
JDK 8 中Stream流中去重的方法 1.简单的去重,可以使用distinct()方法去重,该方法是通过比较equals和hashcode值去去重, 2.复杂的去重, 例如,在一个JavaBean ...
- vim ctags
ctags -I __THROW -I __attribute_pure__ -I __nonnull -I __attribute__ --file-scope=yes --langmap=c:+. ...
- leetcode 实现-168.Excel表列名称
168.Excel表列名称 描述 给定一个正整数,返回它在 Excel 表中相对应的列名称. 例如, 1 -> A 2 -> B 3 -> C … 26 -> Z 27 -&g ...
- CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://mirrors.ustc.edu.cn/anaconda/pkg
conda安装时一直报错,换源什么的都不好使,折腾了半天,直到看到https://blog.csdn.net/u013383596/article/details/87718472 将https改为h ...
- mysql数据按条件导出
仅导出部分数据: mysqldump -hlocalhost -uuser -p --skip-triggers --no-create-info dbname tbname -w "id ...