题意看链接,因为是汉语版的题目。
思路:据说dfs,还是基础的经典dfs。可叹,自己还是不怎么会啊………………
#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<math.h>
using namespace std;
#define inf 10000000
int n,m,s;
void dfs(int num,int leftV,int r,int h,int ls)
{
if(num<=m&&leftV<=0)return ;//层数不够,无剩余体积结束
if(num==m+1&&leftV!=0)return ;//层数到了,但是体积不够或者还有剩余也返回
if(num==m+1&&leftV==0)//当正好符合的时候,比较找一个最小的
{
if(ls<s)
s=ls;
return ;
}
if((m-num+1)*(r-1)*(r-1)*(h-1)<leftV) return ;
//剩余的层数体积最大值和小于剩余体积,结束。(剪枝)
for(int rr=r-1; rr>m-num; rr--)//半径最小的时候不会小于层数的个数(每层的半径为1)
{
for(int hh=m-num+1; hh<h; hh++)//每层最小为1的时候,所以第一次不能小于层数
{
if(num==1)
{
if(rr*rr+2*rr*hh>s)
break;
dfs(num+1,leftV-rr*rr*hh,rr,hh,ls+rr*rr+2*rr*hh);
}
else
{
if(2 * rr * hh + ls >= s || leftV-rr*rr*hh < 0)
break;
dfs(num+1, leftV-rr*rr*hh, rr, hh, ls+2*rr*hh);
}
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
s=inf;
int minR=sqrt(double(n));
dfs(1,n,minR,n,0);
cout<<s<<endl;
}
return 0;
}