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 }