http://poj.org/problem?id=1190
2013-08-10 10:54
351 查看
/* 此题是对半径和高的枚举搜索,但要进行剪枝 */ #include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; int n,m,minv[21],mins[21],best; void dfs(int M,int v,int s,int r,int h) { int i,j,hmax; if(M==0) { if(v==n&&s<best) best=s; return ; } if(v+minv[M]>n||s+mins[M]>=best||2*(n-v)/r+s>=best) return ; //进行剪枝当前体积与剩下M层的最小体积大于n //侧面积与剩下M层的最小侧面积大于等于best /*剩下M层的侧面积为lefts=2*(r[k]*h[k]+...+r[m]*h[m]) , k=(M+1,..,m) lefts>2*(n-v)/r; lefts=best-s; */ for(i=r-1;i>=M;i--) { if(M==m) s=i*i; hmax=min((n-v)/(i*i),h-1); for(j=hmax;j>=M;j--) dfs(M-1,v+i*i*j,s+2*i*j,i,j); } } int main(int argc, char *argv[]) { int i,rmax,hmax; minv[0]=0; mins[0]=0; for(i=1;i<21;i++) mins[i]=mins[i-1]+2*i*i,minv[i]=minv[i-1]+i*i*i; //数组mins,minv记录在该层的最小面积和体积,在等于i时取得; while(cin>>n>>m) { rmax=sqrt(1.0*n)+1; hmax=n/(m*m)+1; best=1000000; dfs(m,0,0,rmax,hmax); if(best==1000000) best=0; cout<<best<<endl; } return 0; }
相关文章推荐
- poj2407简单题目 http://poj.org/problem?id=2407
- poj3295 http://poj.org/problem?id=3295
- C Looooops&&http://poj.org/problem?id=2115
- Sumdiv&&http://poj.org/problem?id=1845&&约数和问题
- http://poj.org/problem?id=2983
- http://poj.org/problem?id=3159
- http://poj.org/problem?id=2255
- http://poj.org/problem?id=2481 树状数组+优先队列
- http://poj.org/problem?id=1861&&Kursal
- http://poj.org/problem?id=1035
- http://poj.org/problem?id=3370
- http://poj.org/problem?id=3468
- http://poj.org/problem?id=3278(bfs)
- http://poj.org/problem?id=3083
- http://poj.org/problem?id=1274&&The Perfect Stall
- http://poj.org/problem?id=1466&&Girls and Boys
- Graph Coloring&&http://poj.org/problem?id=1419最大团问题
- poj 3624 http://poj.org/problem?id=3624
- 青蛙的约会&&http://poj.org/problem?id=1061
- poj 1061 青蛙的约会 二元一次不定方程 http://poj.org/problem?id=1061