生日蛋糕

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外,以上所有数据皆为正整数)

Input

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

Output

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

Sample Input

100

2

Sample Output

68

Hint

圆柱公式 
体积V = πR 2
侧面积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 ;
}

最新文章

  1. 003-常用的Meta标签写法和作用
  2. ConCurrent in Practice小记 (1)
  3. phalcon: crypt-encrypt/decrypt用法
  4. python3获取当前目录(转)
  5. Struts2+JSON+JQUERY DEMO
  6. JAVA异常使用_每个人都曾用过、但未必都用得好
  7. EntityFramework6 用 PostgreSQL
  8. Bash命令行编辑
  9. RabbitMQ --- Routing(路由)
  10. Java filter拦截器的使用
  11. 最大似然估计 (Maximum Likelihood Estimation), 交叉熵 (Cross Entropy) 与深度神经网络
  12. [Linux]出错处理errno
  13. cocso引擎整体流程
  14. 【转】python之配置日志的几种方式
  15. 涂抹mysql笔记-数据库中的权限体系
  16. Selenium 常用定位对象元素的方法
  17. 在window主机上访问virtualbox虚拟机上centos7的tomcat服务
  18. mybatis中预编译sql与非预编译sql
  19. linux基础命令学习(十二)yum命令
  20. TeamViewer13个人版使用中提示为商用版导致无法使用

热门文章

  1. java_第一年_JavaWeb(15)
  2. Codeforces 843D (Dijkstra算法的优化,动态最短路)
  3. H5白屏问题
  4. Neo4j 修改关系类型 type
  5. Elasticsearch7.X 入门学习第九课笔记-----聚合分析Aggregation
  6. ssh1
  7. Linux 使用ansible配置集群间互信
  8. TP框架中的M、D、C、I、A、S方法
  9. 常用Linux Shell命令组合
  10. tomcat启动报错:Neither the JAVA_HOME nor the JRE_HOME environment variable is defined