题目数据范围10000,因此简单的DFS会超时,所以要格外注意剪枝。
1.半径r,与高h都从n+1,开始搜索。
2.当前的表面积,加上之后层的预估最小表面积,若大于最优解,减掉。
3.当前的体积,加上之后层的预估最小体积,若大于最优解,减掉。
4.DFS中,若体积超出限制n,则减掉。
5.(目前体积-已有体积)/r*2+已有的表面积若大于已经得到过的S则减掉。
#include<stdio.h> int r[10001]; int h[10001]; int N,M,S; int miv[21]; int mis[21]; void dfs(int smm,int v,int dep,int h,int r){ if(v>N) return; if(dep==0){ if(v==N&&smm<S){ S=smm; return; } } if(v+miv[dep-1]>N||smm+mis[dep-1]>=S||(N-v)/r*2+smm>S) return; for(int i=r-1;i>=dep;i--){ if(dep==M) smm=i*i; int mxh; if((N-v-miv[dep-1])/(i*i)>h-1) mxh=h-1; else mxh=(N-v-miv[dep-1])/(i*i); for(int j=mxh;j>=dep;j--){ dfs(smm+2*i*j,v+i*i*j,dep-1,j,i); } } } void mx(){ for(int i=1;i<=20;i++){ miv[i]=miv[i-1]+i*i*i; mis[i]=mis[i-1]+2*i*i; } } int main(){ scanf("%d %d",&N,&M); S=99999999;
mx(); dfs(0,0,M,N+1,N+1); if(S==99999999) S=0; printf("%d ",S); return 0; }