您的位置:首页 > 其它

poj 1190 搜索+剪枝

2013-07-30 11:37 337 查看
生日蛋糕

Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 12183 Accepted: 4302
Description

7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。 

设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。 

由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。 

令Q = Sπ 

请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。 

(除Q外,以上所有数据皆为正整数) 

Input

有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
Output

仅一行,是一个正整数S(若无解则S = 0)。
Sample Input
100
2

Sample Output
68

Hint

圆柱公式 

体积V = πR2H 

侧面积A' = 2πRH 

底面积A = πR2 

,太长时间没做搜索了,这道题说句老实话,表示一开始实在没看出来和 搜索 有个毛线的关系,他其实就是用搜索来设置界限,从而优先找到要求解的东西。

这道题剪枝很重要,要不然会超时,包涵下面几类:

如果剩余的最上面几层的最小体积大于剩余需要的体积,那么直接退出:if(minVolume[remainLevel] > remainVolume)
如果当前的面积加上剩余最上面几层的最小面积大于最小面积,那么直接退出:if(currArea + minSurfaceArea[remainLevel] >= minArea)
如果当前层的体积小于剩余层体积平均值,退出当前循环:if(currVolume < remainVolume/remainLevel)
如果当前层的体积大于剩余的体积,进行下一轮循环:if(currVolume > remainVolume)
如果剩余层的最大体积小于需要的体积,那么退出当前循环:if(leftMaxVolume < remainVolume - currVolume)

做到以上的几点即可。

下面是代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int inf=1000000000;
int leftS[21],leftV[21];
int minS;
int V,M;

void init(){//一开始脑残了,题目已经说了每个数据都是正整数,我开始没看见,老是没初始化成
memset(leftS,0,sizeof(leftS));
memset(leftV,0,sizeof(leftV));
for(int i=1;i<=20;++i)
for(int m=0;m<i;++m){
leftS[i]+=(i-m)*(i-m);;
leftV[i]+=(i-m)*(i-m)*(i-m);
}
}

void dfs(int v,int m,int lastR,int lastH,int sumS){
if(m==0&&v==0){
if(sumS<minS){
minS=sumS;
}
return;
}
if(leftS[m]+sumS>=minS) return;
if(leftV[m]>v) return;
int avgV=v/m;
for(int r=lastR-1;r>=m;--r)
for(int h=lastH-1;h>=m;--h){
int curV=r*r*h;
if(curV<avgV)
break;
if(curV>v)
continue;
int leftmaxV=0;
for(int i=1;i<m;++i){
leftmaxV+=(r-i)*(r-i)*(h-i);
}
if(v-curV>leftmaxV) break;
if(m == M) sumS=r*r;
dfs(v-curV,m-1,r,h,sumS+2*r*h);
}
}

int main(){
init();
cin>>V>>M;
minS=inf;
dfs(V,M,sqrt((double)V)+1,V+1,0);
int ans=minS<inf?minS:0;
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: