1710 Birthday Cake (1999 NOI)
1999 NOI National Competition
Title Description Description
July 17 is MR.W's birthday, Acm-thu for this to make a volume of nπ m-layer birthday cake, each layer is a cylinder.
Set from bottom to top number I (1<=i<=m) layer cake is a cylinder with a radius of RI and a height of hi. When I<m, ri>ri+1 and hi>hi+1 are required.
In order to save money as much as possible on the cake, we want the area Q to be the smallest of the outer surface of the cake (except for the bottom surface of the bottom layer).
Make q= sπ
Please program the given N and M to find out the cake making scheme (the appropriate RI and HI values) to make s minimum.
(except Q all of the above data are positive integers)
Enter a description input Description
There are two lines, the first action N (n<=10000), which indicates the volume of the cake to be made is nπ, and the second behavior m (m<=20), which indicates that the layer number of the cake is M.
Outputs description output Description
Only one row, is a positive integer s (if no solution is s=0).
Sample input to sample
100 2
Sample output sample outputs
68
data Size & Hint
Volume v=πr2h
Side area A ' =2πrh
Bottom area A=πr2
Title Analysis: Search questions, in fact, the code is still very good to write the branch.
Reference program:
#include <stdio.h>
#include <string.h>
#define MAXN 22
#define INF 100000000
int n,m,ans,maxh;
M is the layer of the cake, V is the current volume, S is the current area, R and H are the radius and height of the current layer.
void Dfs (int m,int v,int s,int r,int h) {
Exit Criteria
if (M = = 0) {
if (ans > s && v = = N) ans = s;
Return
}
Enumeration of possible solutions
for (int i = r-1; I >= m; i--) {
for (int j = maxh; j >= m; j--) {
if (m = = m) s = i * i;
DFS (M-1,V+I*I*J,S+2*I*J,I,J);
}
}
}
int main () {
scanf ("%d%d", &n,&m);
ans = INF;
maxh=n/m/m;//the only pruning, the maximum height of the underlying cake n/(m*m)
DFS (M,0,0,N+1,N+1);
if (ans = = INF) printf ("0\n");
else printf ("%d\n", ans);
return 0;
}
Then there is the pruning, the condition of four branches:
First hit the table, calculate the minimum volume and surface area of each layer of cake (Minv[i] and mins[i]), and then to reduce the branch
1, v+minv[m] > V
V is already coated volume, then if v plus the next layer of the smallest volume than the overall product of V is larger, this is obviously not possible, minus.
2, s+min[m] > ans
S is already coated area, then s plus the next time the smallest area than the currently obtained ANS is also larger, obviously do not need Dfs, minus.
3. (v-v)/R + S >= ans
Has been painted s, then left rest_s = Sum{2*ri*hi} >= Sum{2*ri*ri*hi/rk} = (v-v)/R (set K as the current layer radius). If rest_s plus S is greater than or equal to ans, then it does not have to be in DFS.
4, Maxh = Min ((n-v-minv[m-1))/(I*i), h-1)
When the enumeration radius is I, the current lowest possible height is maxh = Min ((n-v-minv[m-1])/(I*i), h-1).
Post-Pruning code:
Note: This program cake is numbered from top to bottom (as opposed to the title), Dfs runs from the bottom up.
#include <iostream>
#include <cmath>
using namespace Std;
const int inf=1000000;
const int size=22;
int n,m;
int ans;
int mins[size],minv[size];
int maxh;
void Init () {
mins[0]=minv[0]=0;
for (int i=1;i<=m;i++) {
Mins[i]=mins[i-1]+2*i*i;
Minv[i]=minv[i-1]+i*i*i;
}
}
void Dfs (int m,int v,int s,int lastr,int lasth) {
cout<<m<< ";
if (m==0) {
if (v==n) ans=min (ans,s);
Return
}
if (v+minv[m]>n) return;
if (S+mins[m]>=ans) return;
if (n-v)/lastr+s>=ans return;
for (int r=lastr-1;r>=m;r--) {
int Maxh=min ((n-v-minv[m-1])/(R*R), lasth-1);//note here is minv[m-1], because the total volume n – already have the v– will have the smallest volume minv[m+1] is the maximum volume of M this layer, and then calculate the maximum height
cout<<maxh<<endl;
for (int h=maxh;h>=m;h--) {
if (m==m) s=r*r;//the area of the torus of the entire cake and the table ping, the area of the surface of the bottom cake, plus
DFS (M-1,V+R*R*H,S+2*R*H,R,H);
}
}
}
int main () {
Freopen ("1.in", "R", stdin);
cin>>n>>m;
Ans=inf;
maxh=n/m/m;
Init ();
int maxr=sqrt (N);
DFS (M,0,0,MAXR+1,N+1);
cout<<ans<<endl;
return 0;
}
1710 Birthday Cake (1999 NOI)