搜索第一题(poj 1190)蛋糕

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外,以上所有数据皆为正整数)

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

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

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 int const INF = 1000000000;
 8 int const M = 22;
 9 int RestV[M],RestA[M],ans,mm;
10 int Min(int a,int b)
11 {
12     return a<b?a:b;
13 }
14 void init()
15 {
16      RestV[0]=RestA[0]=0;
17      for(int i=1;i<=20;i++)
18      {
19          RestV[i]=RestV[i-1]+(i*i*i);//m层以下最小的体积
20          RestA[i]=RestA[i-1]+i*i;//m层一下最小的面积
21      }
22 }
23 void dfs(int m,int pr,int ph,int restv,int area)
24 {
25      if(!m)
26      {
27         if(restv==0)ans=Min(ans,area);
28         return ;
29      }
30      if(RestV[m]>restv)return ;
31      if(RestA[m]+area>=ans)return ;
32      int avgv=restv/m;
33      for(int r=pr-1;r>=m;r--)
34      {
35          for(int h=ph-1;h>=m;h--)
36          {
37              int V=r*r*h;
38              if(V>restv)continue;
39              if(V<avgv)break;
40              int restMaxv=0;
41              for(int i=1;i<m;i++)
42                  restMaxv+=(r-i)*(r-i)*(h-i);
43              if(restMaxv+V<restv)break;
44              if(m==mm)area=r*r;
45              dfs(m-1,r,h,restv-V,area+2*r*h);
46          }
47      }
48 }
49 int main()
50 {
51     int n;
52     init();
53     while(~scanf("%d %d",&n,&mm))
54     {
55           scanf("%d %d",&n,&mm)
56           ans=INF;
57           dfs(mm,sqrt((double)n)+1,n+1,n,0);
58           if(ans>=INF)printf("0\n");
59           else printf("%d\n",ans);
60     }
61     return 0;
62 }
View Code
原文地址:https://www.cnblogs.com/nuoyan2010/p/3095234.html