您的位置:首页 > 其它

POJ 1190(dfs剪枝)

2016-04-09 19:15 330 查看
题目大意:要求用m个圆柱构造构造m层的立体,要求该立体体积为n×pi,且外表面积最小。(其中每层的半径、高度都比下一层的要小)

搜索减枝,dfs(r,h,v,d,s)表示当前的半径小于r,高度小于h,构造的体积v,构造的层m,已构造的外表面积。

(ps:所有上底面相加就是最底层的圆面积)

减枝,r和h一定不小于层数,如果当前已构造外表面积s+构造v最优外表面积>=当前最优解,则不需要再搜索。

即  2*v/r+s>=ans(如果没有该减枝,很有可能超时)

/*--------------------------------------------------------
Author:log
Created Time:2016年04月09日 星期六 17时56分02秒
--------------------------------------------------------*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>

using namespace std;

const int inf=0x3f3f3f3f;

int pow3[25];
int ans;
bool dfs(int r,int h,int v,int d,int s){
if(v==0){
if(d!=0)return false;
ans=min(ans,s);
return true;
}
if(d==0){
if(v!=0)return false;
ans=min(ans,s);
return true;
}
if(2*v/r+s>=ans)return false;
for(int R=d;R<r&&R*R*d<=v;R++){
for(int H=max(d,v/(d*R*R));R*R*H<=v&&H<h;H++)
dfs(R,H,v-R*R*H,d-1,s+2*R*H);
}
return false;
}

int main(){
int n;
int m;
scanf("%d",&n);
scanf("%d",&m);
ans=inf;
for(int i=1;i<=m;i++){
pow3[i]=pow3[i-1]+i*i*i;
}
for(int R=m;R*R*m<=n;R++){
for(int H=max(m,n/(m*R*R));R*R*H<=n;H++)
dfs(R,H,n-R*R*H,m-1,2*R*H+R*R);
}
if(ans!=inf)printf("%d\n",ans);
else printf("0\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm dfs poj 搜索