您的位置:首页 > 其它

POJ 1190 生日蛋糕 估计最小答案dfs剪枝

2012-09-07 21:50 417 查看
题意:想做一个m层(每层是一个圆柱)总体积为n*pi的蛋糕抹奶油,想使得抹的奶油的面积/pi = s最小,问最小的s是多少。

题解:化简下得到sigma(ri * ri * hi)= n,s =sigma(2 * ri * hi) + h1 * h1,由于所有的数据都是不确定的没办法dp,只能暴搜了。

很普通的一个剪枝是当前的值+未得到的最小值 >= ans直接跳出,开始从上到下dfs,但是一直TLE,然后看别人代码是从下向上dfs的,

我想是因为大的放在下面的时候剩余需要填充的体积减少的很快,这样会减少dfs的深度。

Sure原创,转载请注明出处。

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <cmath>
#define MIN(a , b) ((a) < (b) ? (a) : (b))
using namespace std;
const int inf = 1 << 29;
int m,n,ans;

void dfs(int v,int c,int sr,int sh,int sum)
{
if(c == m)
{
if(sum < ans)
{
ans = sum;
}
return;
}
if(sum + 2 * v / sr >= ans) return;   //估计剩下的最大的答案剪枝
for(int i=sr;i>=m-c;i--)
{
int bj = v / (i * i) + 1;   //剩下部分的最大h
if(sh < bj) bj = sh;
if(i * i * bj * (m - c) < v) break;   //是否能构成v的体积
if(c == 0) sum = i * i;
for(int j=bj;j>=m-c;j--)
{
if(i * i * j + (i-1) * (i-1) * (j-1) * (m - c - 1) < v) break;    //是否能构成v的体积
if(c < m-1 || i * i * j == v)
{
dfs(v - i * i * j , c+1 , i-1 , j-1 , sum + 2 * i * j);
}
}
}
return;
}

int main()
{
while(~scanf("%d %d",&n,&m))
{
ans = inf;
int rmax = sqrt(1.0 * n / m) + 1;
int hmax = n / m + 1;
dfs(n,0,rmax,hmax,0);
if(ans == inf) ans = 0;
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: