NOI 1999-3 生日蛋糕 解题报告
生日蛋糕
Birthday Cake
Cake.{pas|bas|c}
Cake.exe
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外,以上所有数据皆为正整数)
输入
有两行,第一行为N(N<=10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=20),表示蛋糕的层数为M。
输出
仅一行,是一个正整数S(若无解则S=0)。
样例输入
100 2
样例输出
68
附:圆柱公式
体积V=πR2H
侧面积A’=2πRH
底面积A=πR2
搜索题。
但是,朴素的搜索面临大数据超时的危机-_-||
所以,剪枝是必要的:
最优化剪枝
k层蛋糕的最小表面积可知(h,r都为整数)
当前s可知
那么,s+剩下层数最小表面积>=min最无需再往下搜了
可行性剪枝
k层蛋糕的最小体积minv可知
k层蛋糕的最大体积maxv可知
那么,剩下的体积v不在minv至maxv的范围内,即可停止搜索
最优化剪枝数据越大功力越强..^-^
于是便可以写出程序了.
下面是我的程序,并没有加所有的剪枝……不过AC足够了
//NOI1999-3: CAKE
//2009-1-23: BY Ceeji
//Type : Search
program noi1999_3;
var n,m,i,j,k,l,q,max:longint;
mint,mins:array[0..20]of longint;
procedure gettijimin;
var i,j:longint;
begin
j:=0; mint[1]:=0; mint[0]:=0;
for i:=1 to m-1 do
begin
inc(j,i*i*i);
mint[i+1]:=j;
end;
end;
procedure getsmin;
var i,j:longint;
begin
j:=0; mins[1]:=0; mins[0]:=0;
for i:=1 to m-1 do
begin
inc(j,2*i*i);
mins[i+1]:=j;
end;
end;
procedure sou(i,v,s,h,r:longint); // i: ceng shu; v:ti ji; s:mian ji; h:max {height};
var j,k,l,q:longint;
begin
if (i=m+1)and(v=0)and(max>s)then
begin
max:=s; exit;
end;
if (i>m)or(v< =0) then exit;
for j:=h downto m-i+1 do
begin
for q:=r downto m-i+1 do
begin
if (i=m)and(q*q*j<>v)then continue;
if s+2*q*j+mins[m-i+1]>=max then continue;
if i<>1 then sou(i+1,v-q*q*j,s+2*q*j,j-1,q-1)
else sou(i+1,v-q*q*j,s+2*q*j+q*q,j-1,q-1);
end;
end;
end;
begin
readln(n,m);
max:=100000000;
gettijimin; getsmin;
k:=mint[m];
if n-k< =0 then begin writeln('0'); exit; end;
sou(1,n,0,trunc((n-k)/(m*m)),trunc(sqrt((n-k)/m)));
if max=100000000 then writeln('0') else writeln(max);
end.
题外话:我帮你整理了包括 AI 写作、绘画、视频(自媒体制作)零门槛 AI 课程 + 国内可直接顺畅使用的软件。想让自己快速用上 AI 工具来降本增效,辅助工作和生活?限时报名。
© 转载需附带本文链接,依据 CC BY-NC-SA 4.0 发布。