B24 DFS剪枝 生日蛋糕
视频链接:125 生日蛋糕 DFS剪枝_哔哩哔哩_bilibili
#include <cstring> #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int N=20,INF=1e9; int n,m,ans=INF; int minv[N],mins[N]; //当前层是第u层,第u+1层的半径为R、高度为H //m~u+1层的体积和为v、面积和为s void dfs(int u,int R,int H,int v,int s){ if(u==0){if(v==n)ans=min(ans,s); return;} //边界 if(v+minv[u]>n) return; //cut3:体积和越界 if(s+mins[u]>=ans) return; //cut4:面积和更差 if(s+2*(n-v)/R>=ans) return; //cut5:估价不等式 for(int r=min(R-1,(int)sqrt(n-v));r>=u;r--) for(int h=min(H-1,(n-v)/(r*r));h>=u;h--)//cut1+cut2 dfs(u-1,r,h,v+r*r*h,s+2*r*h+(u==m?r*r:0)); } int main(){ cin>>n>>m; //体积n 层数m for(int i=1; i<=m; i++){ minv[i]=minv[i-1]+i*i*i; //1~i层的最小体积和 mins[i]=mins[i-1]+2*i*i; //1~i层的最小侧面积和 } dfs(m,INF,INF,0,0); //cut1:优化搜索顺序,从大到小 if(ans==INF) ans=0; cout<<ans<<endl; }