(经典搜索例题)生日蛋糕

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 int a[21],b[21],m,n,ans;//a存储表面积,b存储体积 
 7 void search(int v,int s,int p,int r,int h)//v为已用体积,s为已有表面积,p为剩余层数,r为半径,h为高 
 8 {
 9     int i,j,hh;
10     if (p==0)//蛋糕已完成
11     {
12         if (v==n&&s<ans)//判断是否符合要求并得到更优解
13             ans=s;//更新最优解
14         return ;
15     }
16     if(v+b[p]>n) return ;//体积超出 
17     //if(s+a[p-1]>ans) return ;//表面积超出 
18     if(2*(n-v)/r+s>=ans)  return; //重点:余下的侧面积+当前的表面积>当前最优值
19     //剩余表面积FS>=2*V剩/r   
20     //若FS+s>=ans 则不符合 
21      for(i=r-1;i>=p;i--)//枚举上一层的半径
22      {
23         if(p==m) s=i*i;//如果p==m,首先把表面积加上一个底面积才对! 
24         hh=min((n-v-b[p-1])/(i*i),h-1);
25         for(j=hh;j>=p;j--)//枚举上一层的高
26         search(v+i*i*j,s+2*i*j,p-1,i,j);
27      }
28 }
29 int main()
30 {
31       cin>>n>>m;
32       ans=2147483647;
33       a[0]=b[0]=0;
34       for(int i=1;i<21;i++)
35       {
36        //a[i]=a[i-1]+2*i*i;//第i层使用的最大表面积 
37         b[i]=b[i-1]+i*i*i;//第i层使用的最小体积?? 
38       }
39       search(0,0,m,n+1,n+1);//已用体积为0,已用表面积为0 ,将半径和高置为n+1,方便第一层搜索 
40       if(ans==2147483647) cout<<'0';
41       else cout<<ans;
42       return 0;
43 }
原文地址:https://www.cnblogs.com/719666a/p/9508485.html