POJ 1190(深搜)
http://poj.org/problem?id=1190
又有好久没做搜索的题了,没想到做一个卡了我那么久,想哭啊。
一个中文题,思路呢也就是搜索呗,一层一层往上面搜,不过这里有两个比较重要的地方的剪枝。
一、每一次搜索可以达到的最小的半径和高度为当前总的层数减去当前层数(我是默认为最底层是第1层的)。
二、上一层的总面积和加上这一层的最大面积和如果大于最小的表面积的话,直接返回。
1 #include <stdio.h> 2 #include <iostream> 3 #include <string.h> 4 #include <math.h> 5 6 using namespace std; 7 #define INF 9999999 8 9 int s=INF,m,n,ans,mv[21]; 10 11 int dfs(int r,int h,int x,int y) 12 { 13 for(int i=r-1;i>=(n-y);i--) 14 for(int j=h-1;j>=(n-y);j--) 15 { 16 if(x+2*(m-ans)/r>=s) return 0; 17 if(x>s) return 0; 18 if(ans+i*i*j<m&&y!=n&&i!=1&&j!=1){ 19 ans+=i*i*j; 20 if(y==1) x+=i*i; //如果有多层的话,那么表面的总面积和就等于最底下的蛋糕的表面积。(从上往下看) 21 dfs(i,j,x+2*i*j,y+1); 22 if(y==1) x-=i*i; 23 ans-=i*i*j; 24 } 25 if(ans+i*i*j==m&&y==n){ 26 x+=2*i*j; 27 if(y==1) x+=i*i; //如果只有一层的话,那么上表面积也就等于半径的平方。 28 if(x<s) s=x; 29 x-=2*i*j; 30 if(y==1) x-=i*i; //这里记得要减。 31 } 32 } 33 return 0; 34 } 35 36 int main() 37 { 38 scanf("%d%d",&m,&n); 39 ans=0; 40 s=INF; 41 dfs(sqrt(double(m))+1,m+1,0,1); 42 if(s!=INF) printf("%d\n",s); 43 else printf("0\n"); 44 }