/* 此題是對半徑和高的枚舉搜索,但要進行剪枝 */ #include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; int n,m,minv[21],mins[21],best; void dfs(int M,int v,int s,int r,int h) { int i,j,hmax; if(M==0) { if(v==n&&s<best) best=s; return ; } if(v+minv[M]>n||s+mins[M]>=best||2*(n-v)/r+s>=best) return ; //進行剪枝當前體積與剩下M層的最小體積大於n //側面積與剩下M層的最小側面積大於等於best /*剩下M層的側面積為lefts=2*(r[k]*h[k]+...+r[m]*h[m]) , k=(M+1,..,m) lefts>2*(n-v)/r; lefts=best-s; */ for(i=r-1;i>=M;i--) { if(M==m) s=i*i; hmax=min((n-v)/(i*i),h-1); for(j=hmax;j>=M;j--) dfs(M-1,v+i*i*j,s+2*i*j,i,j); } } int main(int argc, char *argv[]) { int i,rmax,hmax; minv[0]=0; mins[0]=0; for(i=1;i<21;i++) mins[i]=mins[i-1]+2*i*i,minv[i]=minv[i-1]+i*i*i; //數組mins,minv記錄在該層的最小面積和體積,在等於i時取得; while(cin>>n>>m) { rmax=sqrt(1.0*n)+1; hmax=n/(m*m)+1; best=1000000; dfs(m,0,0,rmax,hmax); if(best==1000000) best=0; cout<<best<<endl; } return 0; }