(DFS)泰国佛塔

泰囧,大家应该都看过。不知道大家有没有注意到宝宝虔诚祈福的寺庙里的金灿灿的佛塔。      

众所周知,泰国佛塔外面是贴金的,而且金箔过一段时间需要修补。泰国经济自上世纪末就不景气,贴金的开支对于寺庙来说也是个比较大的负担。          

这里请同学来帮助寺庙设计下佛塔的模型,以使佛塔的外表面(最下层的下底面除外)的面积最小。从而节省金箔开支。      

这里抽象佛塔形状为,一层层的圆柱体,自底向上直径递减。制作一个体积为Nπ的M层佛塔。设从下往上数第i(1 <= i <= M)层佛塔是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri> Ri+1且Hi> Hi+1。令外表面面积为Q=Sπ。      

请编程,对于给出的N和M,找出佛塔的制作方案(适当的Ri和Hi的值),使S最小。(除Q外,以上所有数据皆为正整数)

输入包括若干行。每行包括两个整数N(N <= 10000)、M(M <= 20),代表一组测试数据。分别表示待建造的佛塔的体积为Nπ,和佛塔的层数为M。输出对于每组测试数据,输出占一行:一个正整数S(若无解则S = 0)。样例输入

100 2
27 15

样例输出

68
0

利用各种估值进行剪枝,也可以在过程中加入记忆化,效率会更高。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <queue>
 8 #include <set>
 9 #include <map>
10 #include <list>
11 #include <vector>
12 #include <stack>
13 #define mp make_pair
14 //#define P make_pair
15 #define MIN(a,b) (a>b?b:a)
16 //#define MAX(a,b) (a>b?a:b)
17 typedef long long ll;
18 typedef unsigned long long ull;
19 const int MAX=2e5+5;
20 const int INF=1e8+5;
21 using namespace std;
22 //const int MOD=1e9+7;
23 typedef pair<ll,int> pii;
24 const double eps=0.00000001;
25 int san[21];
26 int n,m;
27 int an,now;
28 void dfs(int v,int dep,int R,int H)
29 {
30     if(dep==0)//最后一层的检验
31     {
32         if(v==0&&now<an)
33             an=now;
34         return;
35     }
36     if(v-san[dep-1]<0||now>=an||2*v/R+now>=an)//剪枝  估值函数可利用余下的体积与侧面积之间的关系估计
37         return;
38     for(int r=R-1;r>=dep;r--)
39     {
40         int Hm=min(H-1,(v-san[dep-1])/r/r);//下一层h最大值必小于H
41         //且可计算下一层最大体积,利用公式得这时h最大值   两者中较小的即为下一层高的最大值
42         for(int h=Hm;h>=dep;h--)
43         {
44             if((v-r*r*h)>=0)
45             {
46                 if(dep==m)
47                     now=r*r;
48                 now+=2*r*h;
49                 dfs(v-r*r*h,dep-1,r,h);
50                 now-=2*r*h;
51                 if(dep==m)
52                     now=0;
53             }
54 
55         }
56     }
57 }
58 int main()
59 {
60     for(int i=1;i<=20;i++)
61         san[i]=san[i-1]+i*i*i;//预处理i层最小的体积
62     while(~scanf("%d%d",&n,&m))
63     {
64         an=INF;
65         dfs(n,m,n+1,n+1);
66         if(an==INF)
67             printf("0
");
68         else
69             printf("%d
",an);
70     }
71     return 0;
72 }
原文地址:https://www.cnblogs.com/quintessence/p/7224907.html