生日蛋糕

发布时间 2023-03-22 21:11:36作者: kkidd
#include<iostream>
#include<math.h>
using namespace std;

const int N=30,INF=1e9;

int n,m;
int minv[N],mins[N];//存当前层的最小体积和最小表面积
int ans=INF;
int R[N],H[N];//存每一层的半径和高度

void dfs(int u,int s,int v)
{
    if(mins[u]+s>=ans) return;//如果m~u+1层的总表面积+当前层的最小表面积都比ans大,很显然可以return了
    if(minv[u]+v>n) return;//如果m~u+1层的总体积+当前层的最小体积都比ans大,很显然可以return了
    if(s+2*(n-v)/R[u+1]>=ans) return;//通过数学公式放缩得到的
    if(!u)
    {
        if(v==n) ans=s;
        return;
    }
    for(int r=min(R[u+1]-1,(int)sqrt(n-v));r>=u;r--)
    for(int h=min(H[u+1]-1,(n-v)/r/r);h>=u;h--)
    {
        int t=0;
        if(u==m) t=r*r;
        H[u]=h,R[u]=r;
        dfs(u-1,s+t+2*r*h,v+r*r*h);
    }
}

int main()
{
    cin>>n>>m;
    
    for(int i=1;i<=m;i++)
    {
        minv[i]=minv[i-1]+i*i*i;
        mins[i]=mins[i-1]+2*i*i;
    }
    
    R[m+1]=H[m+1]=INF;
    
    dfs(m,0,0);
    
    if(ans<INF) cout<<ans;
    else puts("0");
    
    return 0;
}