POJ 1190 生日蛋糕

经典搜索题!!送给自己的生日礼物!!!
生日蛋糕

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 20000/10000K (Java/Other)
Total Submission(s) : 7   Accepted Submission(s) : 2
Problem Description
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外,以上所有数据皆为正整数) 
 

Input
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
 

Output
仅一行,是一个正整数S(若无解则S = 0)。
 

Sample Input
1002
 

Sample Output
68
 

Source
PKU
 



AC代码:
 1 //Source Code
 2 
 3 //Problem: 1190        User: CKboss
 4 //Memory: 720K        Time: 16MS
 5 //Language: G++        Result: Accepted
 6 //Source Code
 7 
 8  
 9 #include <iostream>
10 #include <cmath>
11 
12 #define INF 0xffff3f
13 
14 using namespace std;
15 
16 int n,m;
17 
18 int mind[22];
19 int mins[22];
20 double best=INF;
21 
22 void dfs(int k,int r,int h,int S,int D)
23 {
24     int i,j,ld;
25     if(k==m)
26     {
27         if(D==n&&S<best) best=S;//不断替换最小值
28 
29         return ;
30     }
31 
32     ld=n-D;//包括第K层到顶的体积
33     for(i=r-1;i>m-k-1;i--)//枚举可能的半径,(比下面的大,比上面的小)
34     {
35         int maxh,ts=0,td;
36         maxh=(ld-mind[m-k-1])/(i*i)+2;//判断最大高度
37         if(maxh>h-1) maxh=h-1;
38         for(j=maxh;j>m-k-1;j--)
39         {
40 
41             td=ld-i*i*j;
42             if(td<mind[m-k-1])  continue;//1号剪枝
43 
44             if(k==0)
45                 ts=i*i+2*i*j;
46             else
47                 ts=S+2*i*j;
48 
49             if(ts+mins[m-k-1]>=best||ts+2*td/i>=best)  continue;//2号,3号剪枝(3号比较厉害)
50 
51             dfs(k+1,i,j,ts,D+i*i*j);
52         }
53     }
54     return ;
55 }
56 
57 
58 int main()
59 {
60     cin>>n>>m;
61 
62     mind[0]=mins[0]=0;
63     for(int i=1;i<=21;i++)
64     {
65         mind[i]=mind[i-1]+i*i*i;//从顶到 i 的累计最小体积
66         mins[i]=mins[i-1]+2*i*i;//从顶到 i 的累计最小侧面积
67     }
68 
69     dfs(0,sqrt(n)+1,n+1,0,0);//分别以半径为1,或高为1算最大的可能取值
70 
71     if(best!=INF)
72         cout<<best<<endl;
73     else
74         cout<<0<<endl;
75 
76 
77     return 0;
78 }
原文地址:https://www.cnblogs.com/CKboss/p/CKboss.html