题目传送门:http://poj.org/problem?id=1190

参考剪枝:https://blog.csdn.net/nvfumayx/article/details/6653111

生日蛋糕

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 23038   Accepted: 8211

Description

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 = πR2
侧面积A' = 2πRH 
底面积A = πR2 

Source

Noi 99

解题思路:

DFS枚举每层蛋糕的高 H 和 半径 R,要枚举,首先得找出枚举的范围

因为每一层要比上一层少,所以当前层的最小高和半径都等于当前层数。

而最大的高和最大的半径呢?因为高和半径之间的关系 V = r*r*h(省略pi);如果先确定高,求最大半径需要开方,所以不妨先确定最大半径再推最大高。

最大半径可由上一层半径减一得到, 这时最大的高有可能是 上一层的高减一,也有可能是当前层可以达到的最大体积 V / (r*r);

参考上文的两类重要剪枝,其中一类就是极限的思想。即我们极端化求到达每一层时所能累积的最小体积和表面积,即每一层的半径和高都为最小的半径和高。

有了这个预处理,我们便可以进行下面的三个剪枝:
① 当前累积的体积加下剩下的理论最小体积 > 最优值的话OUT;

②同理,如果当前累积的表面积加上剩余的理论最小表面积 > 最优值的话OUT;

③真极限了...

表面积: S = 2*r*h; 体积:V = r*r*h;

由上两式可推出体积与表面积的关系=> V*2/r = S;(即体积一定,半径越大表面积越小);

由于我们的高和半径都是从大到小开始枚举,所以一开始就可以判断如果(当前层最小的表面积) S + (已经累积的表面积)sumS >= 最优值 OUT;

AC code:
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cmath>
 6 #define INF 0x3f3f3f3f
 7 using namespace std;
 8 const int MAXM = 23;
 9 const int MAXN = 1e4+10;
10 int lminQ[MAXM], lminV[MAXM];
11 int min_Q;
12 int N, M;
13
14 ///已经凑的体积,已经凑的表面积,当前在第几层,下一层的半径,下一层的高
15 void dfs(int V, int Q, int step, int r, int h)
16 {
17     if(step == 0)          ///层数用完
18     {
19         if(V == N) min_Q = min(min_Q, Q);  ///体积刚刚好
20         return;
21     }
22     if(V+lminV[step] > N || Q+lminQ[step] > min_Q) return;    //剪枝:如果当前体积加上理论最小体积超过N或者当前表面积加理论最小表面积超过最优值
23     if(2*(N-V)/r + Q >= min_Q) return;                  //剪枝:假设最小的表面积已经大于等于最优值,则没有继续搜的意义了
24     int max_R = r-1;             ///最大半径为上一层半径减一
25     for(int i = max_R; i >= step; i--)  ///枚举半径
26     {
27         if(step == M)        ///当前在最底层
28         {
29             Q = i*i;         ///表面积加上最底层的底面积
30         }
31         int max_H = min(((N-lminV[step-1]-V)/(i*i)), h-1);         ///最大的高度
32         for(int j = max_H; j >= step; j--)
33         {
34             dfs(V+i*i*j, Q+2*i*j, step-1, i, j);
35         }
36     }
37 }
38 int main()
39 {
40     scanf("%d%d", &N, &M);
41     lminQ[0] = 0, lminV[0] = 0;
42     for(int i = 1; i < 22; i++)       ///预处理每一层的理论最小值
43     {
44         lminQ[i] = lminQ[i-1] + 2*i*i;
45         lminV[i] = lminV[i-1] + i*i*i;
46     }
47     min_Q = INF;
48     dfs(0, 0, M, 100, 10000);
49     if(min_Q < INF) printf("%d\n", min_Q);
50     else printf("0\n");
51     return 0;
52 }

转载于:https://www.cnblogs.com/ymzjj/p/9496925.html

POJ 1190 生日蛋糕 【DFS + 极限剪枝】相关推荐

  1. POJ - 1190 生日蛋糕(dfs+剪枝)

    题目链接:点击查看 题目大意:给出生日蛋糕的总体积,以及有多少层,我们要求下面的每一层的高度和半径都要比上面一层的大,并且都是整数,求满足要求的最小表面积 题目分析:因为题目提到了半径和高度都是整数, ...

  2. poj 1190 生日蛋糕

    poj 1190 生日蛋糕 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17460 Accepted: 6221 Descri ...

  3. POJ - 1190 - 生日蛋糕 (深搜剪枝)

    链接: http://poj.org/problem?id=1190 思路: 剪枝. 1.从半径n+1开始 2.当前已有表面积,加上剩余的预估最小表面积,若大于最优解,减掉.(什么是预估最小解?高度每 ...

  4. poj 1190 生日蛋糕 难|供自己瞻仰

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

  5. POJ - 2386 (dfs简单应用)

    POJ - 2386 (dfs深度优先搜索) 题目正文: Due to recent rains, water has pooled in various places in Farmer John' ...

  6. poj 1190(剪枝)

    生日蛋糕 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16191   Accepted: 5751 Description ...

  7. 生日蛋糕 dfs剪枝优化

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

  8. POJ - 1011 Sticks(dfs+剪枝)(好题!!)

    题目链接:点击查看 题目大意:乔治拿来一组等长的木棍,将他们随机砍断,使得每一节木棍的长度都不超过50个单位长度,然后他又想将这些木棍恢复成砍断之前的状态,但他忘记了初始时有多少根木棍以及木棍的初始长 ...

  9. POJ - 3700 Missile Defence System.(dfs+最优性剪枝)

    题目链接:点击查看 题目大意:给出n个导弹的飞行高度,规定一个导弹拦截装置只能拦截严格升序的导弹或严格降序的导弹,问拦截所有导弹需要最少多少个拦截装置 题目分析:之前做过一个dp题,那个题目简单,是只 ...

最新文章

  1. 【原创】ASP.NET C# 压缩和解压缩文件、文件夹函数(测试通过)
  2. 皮一皮:这是什么家族企业?
  3. SharePoint PowerShell 修改计时器任务
  4. c语言 串口中断服务函数,GCC-AVR 编写中断服务函数的注意事项
  5. 高性能服务器开发之C++定时器
  6. 数据分析与挖掘-python常用数据探索函数
  7. 计算机软件中级职称 入职,计算机职调称论文.doc
  8. fritzing导入元件_超屌的 fritzing 新建元件
  9. 信息学奥赛一本通 提高篇 第5章 矩阵乘法
  10. Oracle命令--为数据文件缩容
  11. XML Tree Editor(树形视图XML编辑器) v0.1.0.35
  12. 购买笔记本不得不说的11点应用技巧
  13. OpenShift 4.3 - 基于虚拟机的BareMetal离线安装(1-2)
  14. max os取消开机启动
  15. 使用Excel公式,获取 当前 Excel 文件 的 名字
  16. Linux 镜像文件ISO下载地址、centos网络配置:
  17. idea导入项目爆红问题及解决方案
  18. 微信开发者工具 ETIMEDOUT
  19. 通过这18000个Python项目对比,并从中精选出 45 个值得学习的!
  20. Android开发----MaterialDesign设计下material-dialogs用法

热门文章

  1. 在PHP中模拟asp的response类
  2. 浅谈ASP.NET内部机制(五)
  3. 好分数a1a5_好分数怎么查看班级排名 七年级学生成绩查询
  4. matlab生成m序列的方法
  5. Vivado和Quartus ii 中工程存档(Archive project)及打开
  6. STM32中GPIO的8种工作模式!
  7. 现代神经网络要这么用才能创造智能
  8. 使用resnet训练CIFAR10
  9. SSH项目的简单table及其分页框架
  10. 分析思维导图与绘制思维导图方法介绍