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)