主要思路:
这道题刚拿到就知道要用dfs,但是dfs肯定会T,所以我们要用剪枝来优化搜索的方案数量。
1 要是剩下体积除以最大(虽然取不到)半径所得到的表面积+累计表面积大于答案退出
2 要是剩下来的体积已经小于该层最小体积了就退出
3 还有为了剪枝,我们要起先预处理某一层的最大不可的表面积和体积
4 要是最小面积+当前累计表面积已经比已知答案大了就退出
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #define INF 2147483647 7 using namespace std; 8 int a[201],b[201],m,n,ans;//a存储表面积,b存储体积 9 void dfs(int v,int s,int p,int r,int h) { //v为已用体积,s为已有表面积,p为剩余层数,r为半径,h为高 10 int i,j,yy; 11 if(p==0) { //如果已经搜到了顶层 12 if (v==n&&s<ans)//判断是否符合要求并得到更优解 13 ans=s; 14 return ; 15 } 16 //各种剪枝 17 if(v+b[p-1]>n) return ;//体积超出 18 if(s+a[p-1]>ans) return ;//表面积超出 19 if(2*(n-v)/r+s>=ans) return; //当前的表面积+余下的侧面积>当前最优值 20 for(i=r-1; i>=p; i--) { //枚举半径 21 if(p==m) s=i*i; 22 yy=min((n-v-b[p-1])/(i*i),h-1); 23 for(j=yy; j>=p; j--) //枚举高 24 dfs(v+i*i*j,s+2*i*j,p-1,i,j); 25 } 26 } 27 int main() { 28 cin>>n>>m; 29 ans=INF;//用于输出 30 a[0]=b[0]=0; 31 for(int i=1; i<21; i++) { 32 a[i]=a[i-1]+2*i*i;//第i层使用的最大表面积 33 b[i]=b[i-1]+i*i*i;//第i层使用的最大体积 34 } 35 dfs(0,0,m,n+1,n+1); 36 if(ans==INF) cout<<0; 37 else cout<<ans; 38 return 0; 39 }
请各位大佬斧正(反正我不认识斧正是什么意思)