题目传送门: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

 

解题思路:

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:
 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXM = ;
const int MAXN = 1e4+;
int lminQ[MAXM], lminV[MAXM];
int min_Q;
int N, M; ///已经凑的体积,已经凑的表面积,当前在第几层,下一层的半径,下一层的高
void dfs(int V, int Q, int step, int r, int h)
{
if(step == ) ///层数用完
{
if(V == N) min_Q = min(min_Q, Q); ///体积刚刚好
return;
}
if(V+lminV[step] > N || Q+lminQ[step] > min_Q) return; //剪枝:如果当前体积加上理论最小体积超过N或者当前表面积加理论最小表面积超过最优值
if(*(N-V)/r + Q >= min_Q) return; //剪枝:假设最小的表面积已经大于等于最优值,则没有继续搜的意义了
int max_R = r-; ///最大半径为上一层半径减一
for(int i = max_R; i >= step; i--) ///枚举半径
{
if(step == M) ///当前在最底层
{
Q = i*i; ///表面积加上最底层的底面积
}
int max_H = min(((N-lminV[step-]-V)/(i*i)), h-); ///最大的高度
for(int j = max_H; j >= step; j--)
{
dfs(V+i*i*j, Q+*i*j, step-, i, j);
}
}
}
int main()
{
scanf("%d%d", &N, &M);
lminQ[] = , lminV[] = ;
for(int i = ; i < ; i++) ///预处理每一层的理论最小值
{
lminQ[i] = lminQ[i-] + *i*i;
lminV[i] = lminV[i-] + i*i*i;
}
min_Q = INF;
dfs(, , M, , );
if(min_Q < INF) printf("%d\n", min_Q);
else printf("0\n");
return ;
}

POJ 1190 生日蛋糕 【DFS + 极限剪枝】的更多相关文章

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

    思路:说一下最重要的剪枝,如果当前已经使用了v的体积,为了让剩下的表面积最小,最好的办法就是让R尽量大,因为V = πR 2H,A' = 2πRH,A' = V / R * 2 ,最大的R一定是取当前 ...

  2. POJ 1190 生日蛋糕(DFS)

    生日蛋糕 Time Limit: 1000MSMemory Limit: 10000KB64bit IO Format: %I64d & %I64u Submit Status Descrip ...

  3. poj 1190 生日蛋糕 , 强剪枝

    题意: 制作一个体积为Nπ(N<=10000)的M(M<=20)层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆 ...

  4. POJ 1190 生日蛋糕 剪枝

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

  5. POJ 1190 生日蛋糕题解

    题目地址:http://poj.org/problem?id=1190 一道很有趣的搜索题--主要是剪枝-- 我弄了5个剪枝: 1.当前剩余层数>=上层半径,剪掉 2.当前剩余层数>=上层 ...

  6. Codevs 1710 == POJ 1190 生日蛋糕 == 洛谷P1731

    生日蛋糕 时间限制: 2 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ ...

  7. 洛谷 P1731 [NOI1999]生日蛋糕 && POJ 1190 生日蛋糕

    题目传送门(洛谷)  OR 题目传送门(POJ) 解题思路: 一道搜索题,暴力思路比较容易想出来,但是这道题不剪枝肯定会TLE.所以这道题难点在于如何剪枝. 1.如果当前状态答案已经比我们以前某个状态 ...

  8. poj 1190 生日蛋糕

    中文题 题目分析 搜索题,非常好的剪枝 由于深度一定(m),所以使用深度优先搜索,自上而下的设定蛋糕序号,最顶层的为第1层,……,最底层的蛋糕为第m层,很明显满足题目条件的前i层的(从顶层(也就是编号 ...

  9. poj 1190 DFS 不等式放缩进行剪枝

    F - (例题)不等式放缩 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submi ...

随机推荐

  1. Gradle发布项目到 maven 之gradle-bintray-plugin(2)

    上传的方式有两种,第一种是通过 bintray 官方出的插件 bintray/gradle-bintray-plugin 第二种是一个国外组织开源的插件 novoda/bintray-release ...

  2. oracle 备份恢复篇(一)---rman

    一,rman介绍 RMAN(Recovery Manager)是随Oracle服务器软件一同安装的工具软件,它可以用来备份和恢复数据库文件.归档日志和控制文件,用来执行完全或不完全的数据库恢复.与传统 ...

  3. 安装Newton版Glance

    Image Service 本文介绍在controller节点上安装.配置Image服务 glance,镜像存储在本地文件系统 安装准备 controller 节点 ip:192.168.81.11 ...

  4. 昨天太晚了,今天教你用Debug模式来分析程序执行顺序

    还是以昨天的XML文件解析来做栗子,希望通过这个好吃的栗子可以举一反三 学会用debug来看源码和找Bug 事件类型主要有五种START_DOCUMENT:xml头的事件类型    = 0END_DO ...

  5. c#特性类 Attribute

    Attribute FYI Link: Attribute在.net编程中的应用(一) Attribute在.net编程中的应用(二) Attribute在.net编程中的应用(三) Attribut ...

  6. bzoj 4574: [Zjoi2016]线段树

    Description 小Yuuka遇到了一个题目:有一个序列a_1,a_2,?,a_n,q次操作,每次把一个区间内的数改成区间内的最大值,问 最后每个数是多少.小Yuuka很快地就使用了线段树解决了 ...

  7. [转]浅谈微信小程序

    本文转自:http://www.cnblogs.com/liziyou/p/6340159.html 微信小程序 1.什么是小程序 小程序是指微信公众号平台小程序,小程序可以在微信内被便捷的获取和转播 ...

  8. 破解jar包5步搞定,jira7.9.2操作成功,附github代码库

    1,从要破解的程序中拷贝.jar包文件,运行1_jar.sh将其解压.以jira7.9.2为例: $install_dir\JIRA\atlassian-jira\WEB-INF\lib\atlass ...

  9. C# 矩阵运算和一些基本的几何运算

    以前工作中写的,这里备个份,有可能用到 基本的矩阵运算类,测试20阶以内应该没啥问题,超过20阶不好使... /// <summary> /// 矩阵 异常 512索引 1024无解 20 ...

  10. 微服务学习笔记一:Spring Cloud简介

    1.Spring Cloud是一个工具集:Spring   Cloud是在Spring    Boot的基础上构建的,用于简化分布式系统构建的工具集:使架构师在创建和发布微服务时极为便捷和有效. Sp ...