『生日蛋糕 搜索剪枝』


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 Format

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

Output Format

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

Sample Input

100
2

Sample Output

68

解析

预备知识:圆柱体体积公式\(v=\pi R^2H\),圆柱体侧面积公式\(s'=2\pi RH\),圆柱体底面积公式\(s=\pi R^2\)

输出和输入均不考虑\(\pi\),所以直接无视所有公式中的\(\pi\)即可。

直接考虑一个搜索算法,状态为\((dep,s,v)\),代表当前搜索到第\(dep\)层(从上往下数),表面积为\(s\),体积为\(v\),并且记录了第\(m\)至第\(dep-1\)层的高度和半径为\(h\),\(r\)数组(小写)。然后对于每一层,枚举其高度\(H\)和半径\(R\),进行搜索。

然后考虑如下的剪枝:

  • 上下界剪枝:枚举\(R \in [dep,min(\lfloor \sqrt{n-v} \rfloor,r_{dep+1}-1)],H\in [dep,min(\lfloor \frac{n-v}{R^2} \rfloor,h_{dep+1}-1)]\)

由于蛋糕\(dep\)层以上还有\(m-dep\)层,高度和半径大小的要求都是递减的,所以枚举的左边界很容易得到。

对于半径,其枚举右边界显然不能大于等于\(r_{dep+1}\),不然不满足递减性,假设第\(dep\)层就是最后一层,那么由圆柱体体积公式\(\pi R^2H=\pi (n-v)\)可以得到半径\(R\)显然需要满足\(R \leq \sqrt{n-v}\),这就是半径的枚举范围。

对于高度,同样右边界不能大于等于\(h_{dep+1}\),不然不满足递减性,由于已知\(R\),那么我们也可以用体积公式得到高度\(H\)显然需要满足\(H \leq \frac{n-v}{R^2}\),这就是高度的枚举范围。

  • 搜索顺序剪枝:对于以上推导出的枚举范围,从大到小枚举。
  • 可行性及最优性剪枝:预处理从上向下\(i\)层的最小侧面积及体积,即第\(i\)层半径高度都取\(i\),最小体积\(v_i=i^3\),最小表面积\(s_i=2*i^2\)。如果体积\(v\)加上剩下\(dep+1\)到\(1\)的最小体积和大于\(n\)时,可以剪枝。如果表面积\(s\)加上剩下\(dep+1\)到\(1\)的最小表面积和大于已经搜到的答案时,可以剪枝。
  • 最优性剪枝:当\(\frac{2(n-v)}{r_{dep}}+s\)大于等于已经搜到的答案时,可以剪枝。

由圆柱体表面积与体积公式可以得到第\(1\)到第\(dep-1\)层的体积之和为
\[
\sum_{i=1}^{dep-1}(h_i*r_i^2) =n-v
\]
侧面积之和为
\[
2\sum_{i=1}^{dep-1}(h_i*r_i)
\]
那么可以进行如下推导:
\[
2\sum_{i=1}^{dep-1}(h_i*r_i)
\\=\frac{2}{r_{dep}}\sum_{i=1}^{dep-1}(h_i*r_i)*r_{dep}
\\ = \frac{2}{r_{dep}}\sum_{i=1}^{dep-1}(h_i*r_i*r_{dep})
\\ \geq \frac{2}{r_{dep}}\sum_{i=1}^{dep-1}(h_i*r_i^2)
\\ =\frac{2(n-v)}{r_{dep}}=x
\]
即第\(1\)到第\(dep-1\)层的表面积之和大于等于\(x\),所以如果\(s+x\)大于等于已经搜到的答案时,也可以剪枝。

很多时候,\(dfs\)的剪枝是可以通过如上的缩放方式推导出来的,这就要求我们需要发现题目隐藏的性质,合理利用已知条件进行优化。

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
#define mset(name,val) memset(name,val,sizeof name)
#define filein(str) freopen(str".in","r",stdin)
#define fileout(str) freopen(str".out","w",stdout)
const int N=10000+20,M=20+20,INF=0x3f3f3f3f;
int n,m,h[M],r[M],Minsumv[M],Minsums[M],ans=INF;
inline void input(void)
{
    scanf("%d%d",&n,&m);
}
inline void init(void)
{
    for(int i=1;i<=m;i++)
    {
        Minsumv[i]=Minsumv[i-1]+(i*i*i);
        Minsums[i]=Minsums[i-1]+(2*i*i);
    }
    h[m+1]=r[m+1]=INF;
}
inline void dfs(int dep,int s,int v)
{
    if(!dep)
    {
        if(v==n)ans=min(ans,s);
        return;
    }
    if(2*(n-v)/(r[dep+1])+s>ans)return;
    if(v+Minsumv[dep]>n)return;
    if(s+Minsums[dep]>ans)return;
    for(int R=min((int)sqrt((n-v)*1.0),r[dep+1]-1);R>=dep;R--)
    {
        for(int H=min((n-v)/(R*R),h[dep+1]-1);H>=dep;H--)
        {
            r[dep]=R;h[dep]=H;
            if(dep==m)
                dfs(dep-1,R*R+2*R*H,R*R*H);
            else dfs(dep-1,s+2*R*H,v+R*R*H);
        }
    }
}
int main(void)
{
    input();
    init();
    dfs(m,0,0);
    printf("%d\n",ans==INF?0:ans);
    return 0;
} 


『生日蛋糕 搜索剪枝』

原文地址:https://www.cnblogs.com/Parsnip/p/10610751.html

时间: 2024-10-13 05:53:38

『生日蛋糕 搜索剪枝』的相关文章

2017-2018-2 20155303『网络对抗技术』Exp5:MSF基础应用

2017-2018-2 20155303『网络对抗技术』Exp5:MSF基础应用 --------CONTENTS-------- 一.原理与实践说明 1.实践内容 2.预备知识 3.基础问题 二.实践过程记录 1.Windows服务渗透攻击--MS08-067安全漏洞 2.浏览器渗透攻击--MS11-050 3.针对Office软件的渗透攻击--MS10-087 4.针对Adobe Reader软件的渗透攻击--adobe_toolbutton 5.快捷方式图标漏洞--ms10-046 6.M

2017-2018-2 20155303『网络对抗技术』Exp6:信息收集与漏洞扫描

2017-2018-2 20155303『网络对抗技术』 Exp6:信息收集与漏洞扫描 --------CONTENTS-------- 一.原理与实践说明 1.实践内容 2.基础问题 二.实践过程记录 1.信息收集 1.1通过DNS和IP挖掘目标网站的信息 1.2通过搜索引擎进行信息搜集 1.3活跃主机扫描 1.4nmap的使用 1.5网络服务扫描 2.漏洞扫描 三.实践总结及体会 附:参考资料 一.原理与实践说明 1.实践内容 本实践的目标是掌握信息搜集的最基础技能.具体有: 各种搜索技巧的

2017-2018-2 20155310『网络对抗技术』Exp5:MSF基础应用

2017-2018-2 20155310『网络对抗技术』Exp5:MSF基础应用 基础问题回答 用自己的话解释什么是exploit,payload,encode exploit:由攻击者或渗透测试者利用一个系统.应用或服务中的安全漏洞 payload:攻击载荷,如后门等攻击代码. encode:指编码,对我们的程序或代码进行伪装. 实验内容 一个主动攻击实践,如ms08_067 1.启用msf终端msfconsole 2.然后使用search命令搜索该漏洞对应的模块:search ms08_06

2017-2018-2 20155303『网络对抗技术』Exp9:Web安全基础

2017-2018-2 『网络对抗技术』Exp9:Web安全基础 --------CONTENTS-------- 一.基础问题回答 1.SQL注入攻击原理,如何防御? 2.XSS攻击的原理,如何防御? 3.CSRF攻击原理,如何防御? 二.实践过程记录 1.General ①Http Basics 2.Code Quality ①Discover Clues in the HTML 3.Cross-Site Scripting(XSS) ①Phishing with XSS ②Stored X

首届中国域名节落户深圳,『创新之都』再迎浪潮

深圳享有得天独厚的地理位置优势,在交通.经济发展.气候和文化影响等方面,深圳亦比其他城市更有着发展潜力.特别在随着改革开放的脚步之后,深圳在贸易.信息技术建设等方面亦上升到新的高度,这些源自环境.人文和政治等多方面的因素,都无一例外地使得深圳成为一个仅次于北京和上海之后的新型内陆城市,正迎来全新的发展时机.这些天然优势因素的集合,都使得深圳作为一个朝气蓬勃的城市,在即将到来的信息时代里,可以全方面发展经济与文化之外的信息技术.互联网商业效应等模式. 即将于12月19日在深圳举行的首届中国域名节,

【搜索剪枝】HDU 5469 Antonidas

通道 题意:给出1字母树,询问一字符串是否出现在该树中 思路:直接搜索剪枝,有人点分治?写了几发都T了..有人会了教我? 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct Edge { int v, nxt; Edge () { } Edge (int _v, int _n) { v = _v, nxt = _n; } }; const in

poj 1054 The Troublesome Frog (暴力搜索 + 剪枝优化)

题目链接 看到分类里是dp,结果想了半天,也没想出来,搜了一下题解,全是暴力! 不过剪枝很重要,下面我的代码 266ms. 题意: 在一个矩阵方格里面,青蛙在里面跳,但是青蛙每一步都是等长的跳, 从一个边界外,跳到了另一边的边界外,每跳一次对那个点进行标记. 现在给你很多青蛙跳过后的所标记的所有点,那请你从这些点里面找出 一条可能的路径里面出现过的标记点最多. 分析:先排序(目的是方便剪枝,break),然后枚举两个点,这两个 点代表这条路径的起始的两个点.然后是三个剪枝,下面有. 开始遍历时,

USACO/fence8 迭代加深搜索+剪枝

题目链接 迭代加深搜索思想. 枚举答案K,考虑到能否切出K个木头,那么我们当然选最小的K个来切. 1.对于原材料,我们是首选最大的还是最小的?显然,首选大的能够更容易切出,也更容易得到答案. 2.对于目标木头,我们是优先得到最大的还是最小的?显然,由于K个木头我们都要得到,那么当然先把最大的(最难得到的)先得到,这种搜索策略更优. 3.假设总原材料为all,前K个木头总和为sum,那么all-sum就是这一次切割过程中能[浪费]的最大数目.对于一个切剩下的原材料,若它比最小的目标木头还要小,则它

hdu 5887 搜索+剪枝

Herbs Gathering Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 687    Accepted Submission(s): 145 Problem Description Collecting one's own plants for use as herbal medicines is perhaps one of t