Birthday Cake (dfs + pruning)

Birthday Cake

 POJ - 1190 

topic:

July 17 is Mr.W birthday, ACM-THU for this volume to create a birthday cake Nπ the M layer, each layer is a cylinder. 
Provided from the bottom up of the number i (1 <= i <= M) layer cake with a radius Ri, a cylindrical height Hi. When i <M, the required Ri> Ri + 1 and Hi> Hi + 1. 
Due to the cake buttering, cost reduction is possible, we want an outer surface of the cake (the lowermost layer under the bottom surface excluding) the area of the smallest Q. 
So that Q = Sπ 
program a given pair N and M, to find cake recipe programs (appropriate value Ri and Hi), the minimum of S. 
(Q addition, all the above data are all positive integer) 

Input

There are two rows, the first row N (N <= 10000), represents the volume of the cake to be made of n [pi]; second row M (M <= 20), indicates the number of layers of cake M.

Output

Only one row is a positive integer S (if no solutions are S = 0).

Sample Input

100

2

Sample Output

68

Hint

Cylindrical formula 
volume = [pi] R V  2
side area A '= 2πRH 
bottom area of [pi] R = A  2 

 

Ideas:

         It is easy to know is dfs according to the number of layers. When the number of layers conditions and volume conditions are met, the answers can find the smallest output. Why just wanted to write this topic out of it? Because this topic requires time seemingly relaxed, but in reality people want to vomit blood. Dfs need to write out a large amount of pruning, especially on oj hnust requirements for pruning is simply ...... too strict. There is a major need for pruning of three categories:

1) n + minv [m 1-]> N has calculated the current volume of the cake, with the result the volume of the remaining layers may be manufactured with minimal cake if more than n, cut.

2) sum + mins [m-1]> ans has calculated the current surface area of ​​the cake, together with the remaining layers when the result of the surface area may produce the result of the least cake (ANS) if more than the previously calculated , cut.

3) sum + 2 * (Nn) / r> = ans mathematical formula is derived: n-sumv both referred to as the surface area of ​​the remaining volume is needed dv s

         s = 2 * nd * hi * r 2 + (i-1) * h (i-1) + ...> = 2 * nd * hi * ri / r + 2 * r (i-1) * h ( i-1) * r (i-1) / r + ...

                             = 2 * dv / r (i taken from the M-1, r is the current radius ri / r <1)

     It is also needed to give a minimum surface area s = 2 * (n-sum) / r, s and if the smallest surface area has been searched than the sum ans still would not continue searching the large

If you still overrun time if (for example, in data hnust provided) will need to prune the fourth time.

4) The current volume is calculated, a result of adding the maximum possible volume of the cake is less than n, cut. This is a reference to the idea of ​​big brother, do not stick out, you can find it

 

AC Code:

#include<bits/stdc++.h>

using namespace std;
int h,r,N,M,mins[25],minv[25];
const int inf=1<<30;
int ans=inf;
int sum=0;
void dfs(int r,int h,int n,int m,int sum)
{
    if(m==0)
    {
        if(n==N&&sum<ans)
        {
            ans=sum;//cout<<r<<" "<<h<<endl;
        }
        return;
    }
    if(n+minv[m-1]>N||sum+mins[m-1]>ans||sum+2*(N-n)/r>=ans)
        return;
    for(int i=r-1; i>=m; i--)
    {
        int jl=i*i;
        if(m==M)
            sum=jl;
        int maxh=((N-n-minv[m-1])/(i*i)<h-1)? (N-n-minv[m-1])/(i*i):h-1;
         For ( int J = maxH; J> = m; J, ) 
        { 
            DFS (I, J, n- + JL * J, M- . 1 , SUM + 2 * I * J); 
        } 
    } 
} 
int main () 
{ 
    MINV [ 0 ] = 0 ; 
    mins [ 0 ] = 0 ;
     for ( int I = . 1 ; I <= 20 is ; I ++) // calculated from the top downwardly minimum volume and surface area of the possible values 
    {
         // from the top (i.e. minimum volume MINV [i] of the first layer) to the i-th layer at the time of establishment of the j-th layer are the radius and height j 
        MINV [i] = MINV [I-. 1 ] + I * I * I; 
        mins [I] = mins [I- . 1 ] + 2 * I * I; 
    } 
    the while (Scanf ( " % D% D " , & N, & M) == 2 ) 
    { 
        ANS = INF;
         int Rmax of = ( int ) sqrt (( Double ) N); // Rmax of the maximum radius to the initial radius bottom sqrt (n-) 
        int Hmax of N =;                     // Hmax of the maximum height of the initial n- 
        DFS (Rmax of, Hmax of, 0 , M, 0 );
         IF (ANS == INF) 
            COUT<<0<<endl;
        else
            cout<<ans<<endl;
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/lavena/p/11231974.html