B24 DFS剪枝 生日蛋糕

视频链接:125 生日蛋糕 DFS剪枝_哔哩哔哩_bilibili

Luogu P1731 [NOI1999] 生日蛋糕

#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;
}

 

posted @ 2023-06-20 20:24  董晓  阅读(313)  评论(0编辑  收藏  举报