此题足可以见得dfs适用的范围之广
在说题解之前有一个很重要的一点就是:要求的S其实分为两部分,每层圆柱的侧面积+每层上面的环形面积,但是那所有的环形面积加起来就是最下面一层的面积,这是一个小技巧。
下面剪枝就不难了,1、面积用不完。2、面积不够用。 解析看代码
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int v,m;
int ans;
void dfs(int prer,int preh,int vv,int sum,int ceng)//分别代表:上一层的r、h,剩余面积
{ //当前面积和、层数(从下往上搜)
if(vv==0&&ceng==0)
{
if(ans!=0&&sum<ans)
ans=sum;
else if(ans==0)
ans=sum;
return;
}
if(vv>((prer-1)*(prer-1)*(preh-1)*ceng)) //体积用不完,因为往上体积越来越小
return;
if(m<=0||vv<=0||(sum>ans&&ans!=0)) //这个很好理解,就是越界
return;
for(int i=prer-1;i>=ceng;i--)
{
for(int j=preh-1;j>=ceng;j--)
{
int curv=i*i*j;
int curs=2*i*j;
if(ceng==m) curs+=i*i;
if(sum+2*vv/i>=ans&&ans!=0) continue;//2*vv/i是剩余vv最小但不可能的侧面积之和了
dfs(i,j,vv-curv,sum+curs,ceng-1);
}
}
}
int main()
{
cin>>v>>m;
dfs(100,1000,v,0,m);
cout<<ans<<endl;
return 0;
}