宇宙说你不是孤独的.|

Momo·Trace

园龄:3年3个月粉丝:6关注:1

[NOI1999] 生日蛋糕

看题
洛谷传送门

点击查看复杂的题目

题目背景

数据加强版 link

题目描述

7 月 17 日是 Mr.W 的生日,ACM-THU 为此要制作一个体积为 NπM 层生日蛋糕,每层都是一个圆柱体。

设从下往上数第 i1iM)层蛋糕是半径为 Ri,高度为 Hi 的圆柱。当 i<M 时,要求 Ri>Ri+1Hi>Hi+1

由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 Q 最小。

请编程对给出的 NM,找出蛋糕的制作方案(适当的 RiHi 的值),使 S=Qπ 最小。

(除 Q 外,以上所有数据皆为正整数)

输入格式

第一行为一个整数 NN2×104),表示待制作的蛋糕的体积为 Nπ

第二行为 MM15),表示蛋糕的层数为 M

输出格式

输出一个整数 S,若无解,输出 0

样例 #1

样例输入 #1

100
2

样例输出 #1

68

示例图:image

样例 #1

样例输入 #1

100
2

样例输出 #1

68

ok,开始愉快的AC之旅

第一步:预处理

定义 a,b数组,存储第i层最多能用的表面积和体积,便于优化


第二步:深度优先搜索

定义search函数,负责搜索

递归结束条件是:

1:蛋糕已完成,即层数p==m

2:体积超过了预定的值,或者表面积超过了之前存储的最小值ans


第三步:寻找优化方案!

这步尤为重要,没有合适的优化方案会导致超时

1:对于体积
在第一步已经完成了对最大体积的预处理,所以只需要用当前体积加上b[i-1],判断是否大于了规定体积n即可

即: if(v+b[p-1]>n) return ;//体积超出

2:对于表面积
如果 当前的表面积+余下的侧面积>当前最优值ans (这个应该很简单证明)

但是,如何实现呢???

于是就有了接下来的公式推理

设已经做了i层蛋糕,则还需做m-i层,
Si’:为第i层蛋糕的侧面积,
FSi:余下的侧面积
根据定义:
V=π*R*R*H(在这里统一删掉π)
则有:
2Vi= 2R[i+1] * R[i+i] * H[i+1] + ...+ 2Rm * Rm * Hm
(每一层的体积之和)
= R[i+1] * S[i+1]’ + ...+ Rm * Sm’
R[i+1] * (S[i+1]’+ ...+ Sm’) 放缩法
= R[i+1]*FSi (剩余侧面积)
所以:
FSi ≥ 2Vi / Ri+1

因此,剪枝条件变为了

2*(n-v)/r+s>=ans

于是前面预处理的a数组就可以去掉了

第三步完成

综合这三步编写代码,愉快的AC

#include<bits/stdc++.h>
using namespace std;
int a[21],b[21],m,n,ans;//a存储表面积,b存储体积
void search(int v,int s,int p,int r,int h)//v为已用体积,s为已有表面积,p为剩余层数,r为半径,h为高
{
int i,j,hh;
if (p==0)//蛋糕已完成
{
if (v==n&&s<ans)//判断是否符合要求并得到更优解
ans=s;//更新最优解
return ;
}
if(v+b[p-1]>n) return ;//体积超出
//if(s+a[p-1]>ans) return ;//表面积超出
if(2*(n-v)/r+s>=ans) return; //重点:当前的表面积+余下的侧面积>当前最优值
//剩余表面积FS>=2*V剩/r
//若FS+s>=ans 则不符合
for(i=r-1;i>=p;i--)//枚举上一层的半径
{
if(p==m) s=i*i;
hh=min((n-v-b[p-1])/(i*i),h-1);
for(j=hh;j>=p;j--)//枚举上一层的高
search(v+i*i*j,s+2*i*j,p-1,i,j);
}
}
int main()
{
cin>>n>>m;
ans=2147483647;
a[0]=b[0]=0;
for(int i=1;i<21;i++)
{
//a[i]=a[i-1]+2*i*i;//第i层使用的最大表面积
b[i]=b[i-1]+i*i*i;//第i层使用的最大体积
}
search(0,0,m,n+1,n+1);
if(ans==2147483647) cout<<'0';
else cout<<ans;
return 0;
}
posted @   Momo·Trace  阅读(70)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示