Title Link: Poke me
Pruning search questions
We consider enumerating each layer from large to small
- If the current volume is greater than the total volume return
- When enumerating the next layer is [the remaining layers, the - 1 of the previous layer]
- If the current area plus the possible maximum area is still larger than ans, return
- If the current volume plus the possible minimum volume is smaller than n, return
- Area calculation directly brings in parameters, do not reopen function calculation
- h,r enumeration from \ (\ sqrt n \)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<ctime> #define MAXN 20 using namespace std; int n,m; int r[MAXN],h[MAXN]; int ans=2147483647; inline int sqr(double x){return x*x;} inline int calc() { // for(int i=1;i<=m;i++) printf("i=%d r=%d h=%d\n",i,r[i],h[i]); int cur_ans=0; for(int i=1;i<=m;i++) cur_ans+=r[i]*h[i]; return cur_ans; } inline void search(int pos,int now,int cans) { if(cans+(m-pos+1)+r[1]*r[1]>ans&&pos<=m) return;//The measure of area if(now+(m-pos+1)*sqr(r[pos-1])*(h[pos-1])<n&&pos<=m) return;//volume if(pos>m) { if(now==n) { cans+=r[1]*r[1]; ans=min(ans,cans); } return; } for(int i=r[pos-1]-1;i>=m-pos+1;i--) { for(int j=h[pos-1]-1;j>=m-pos+1;j--) { if(now+sqr(i)*j<=n) { r[pos]=i; h[pos]=j; search(pos+1,now+sqr(i)*j,cans+2*i*j); r[pos]=0,h[pos]=0; } } } } int main() { #ifndef ONLINE_JUDGE freopen("ce.in","r",stdin); // freopen("ce.out","w",stdout); #endif scanf("%d%d",&n,&m); h[0]=(int)sqrt(n); r[0]=(int)sqrt(n); search(1,0,0); printf("%d\n",ans); // cout<<(double)clock()/CLOCKS_PER_SEC<<endl; return 0; }