题目大意:
制作体积为Nπ的M层蛋糕,要求从上到下半径递减,高递减。输出使表面积Sπ最小的S。(N<=20000)(M<=15)。
思路:
搜索,以下是几个剪枝:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 6 using namespace std; 7 8 int n,m,lifang[5000],s,mins,cnt[60],te; 9 10 void init() 11 { 12 lifang[1]=1; 13 for(int i=2;i<=m;i++) 14 { 15 lifang[i]=lifang[i-1]+i*i*i; 16 } 17 return ; 18 } 19 20 void dfs(int ceng,int tiji,int rr,int hh) 21 { 22 if(ceng==m+1) 23 { 24 if(tiji==0) 25 { 26 mins=min(mins,s); 27 } 28 return ; 29 } 30 if(tiji-lifang[m-ceng+1]<0)return ;//以后按最小搭,余下的也体积不够。 31 if(ceng!=1) 32 { 33 long long tem=0;//以后按最大搭,余下的体积还有多余。 34 for(int i=1;i<=m-ceng+1;i++) 35 { 36 tem+=(rr-i)*(rr-i)*(hh-i); 37 } 38 if(tiji>tem)return ; 39 } 40 int t1,t2,t3; 41 t2=m-ceng+1;//最小值 42 if(s+t2*(t2+1)*(2*t2+1)/3>=mins)return ;//以后表面积的最小值加上也比当前最优解大。 43 t1=sqrt((tiji-lifang[t2-1])/t2);//半径最大值。 44 t1=min(rr-1,t1); 45 t3=(tiji-lifang[t2-1])/(t2*t2);//高最大值 46 t3=min(hh-1,t3); 47 if(t2>t1)return ; 48 if(t2>t3)return ; 49 for(int r=t1;r>=t2;r--)//这个枚举顺序非常关键 50 { 51 for(int h=t2;h<=t3;h++) 52 { 53 s+=(h*r*2); 54 if(ceng==1)s+=r*r; 55 if((s>mins)||(tiji-r*r*h<lifang[t2-1]))//同第三个和第一个剪枝 56 { 57 s-=(h*r*2); 58 if(ceng==1)s-=r*r; 59 break; 60 } 61 dfs(ceng+1,tiji-r*r*h,r,h); 62 s-=(h*r*2); 63 if(ceng==1)s-=r*r; 64 } 65 } 66 return ; 67 } 68 69 int main() 70 { 71 scanf("%d%d",&n,&m); 72 mins=0x7fffffff; 73 init(); 74 dfs(1,n,mins,mins); 75 if(mins==0x7fffffff) 76 { 77 printf("0\n"); 78 return 0; 79 } 80 printf("%d\n",mins); 81 return 0; 82 }
原文:https://www.cnblogs.com/LiqgNonqfu/p/9966868.html