P1731 [NOI1999]生日蛋糕
搜索+剪枝
常见的剪枝:
若当前状态+后面所要搜索的最差的状态$>$或是$<$最后的状态,就返回
预处理最差的状态
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; //const double pi=3.1415926535; int n,m; int h[20],r[20],S,t_h,s_v[15]; void dfs(int k,int s,int v){ if(s+r[m]*r[m]>S) return; if(k==0){if(v==n){S=s+r[m]*r[m];}return;} if(v+(r[k+1]-1)*(r[k+1]-1)*(h[k+1]-1)*k<n) return; if(v+s_v[k]>n) return; for(int i=r[k+1]-1;i>=k;i--){ for(int j=h[k+1]-1;j>=k;j--){ if(v+i*i*j<=n) { r[k]=i,h[k]=j; dfs(k-1,s+2*i*j,v+i*i*j); r[k]=0,h[k]=0; } } } } int main() { scanf("%d%d",&n,&m); t_h=sqrt(n); r[m+1]=h[m+1]=t_h; S=0x7fffffff; for(int i=1;i<=m;i++) s_v[i]=i*i*i+s_v[i-1]; dfs(m,0,0); printf("%d ",S); return 0; }