生日蛋糕

这是一道绝妙的搜索剪枝题

#include<bits/stdc++.h>
using namespace std;
int n,m,anss=1e9;
int h[20],r[20];
void dfs(int step,int v,int s){
    if(v+step*step*step>n)return;//粗略估计的最小体积
    if(s+r[m]*r[m]>=anss||2*(n-v)/r[step+1]+s>anss)return;//粗略估计的最小表面积和放缩之后的最小表面积
    if(step==0)
     if(v==n)return anss=s+r[m]*r[m],void();//如果到达终点
     else return;
    for(int x=min((int)sqrt(n-v),r[step+1]-1);x>=step;x--)//可以由体积公式得到
       for(int y=min((int)(n-v)/(x*x),h[step+1]-1);y>=step;y--)//可以由面积公式得到
        r[step]=x,h[step]=y,dfs(step-1,v+r[step]*r[step]*h[step],s+2*r[step]*h[step]);
}
int main(){
    scanf("%d%d",&n,&m);
    h[m+1]=sqrt(n);r[m+1]=sqrt(n);//粗略估计的高和底
    dfs(m,0,0);
    if(anss==1e9)puts("0");
    else cout<<anss<<endl;
}

 

posted @ 2019-09-08 21:00  Coder_cjh  阅读(227)  评论(0编辑  收藏  举报