POJ1190 生日蛋糕(DFS)

来源:互联网 发布:淘宝懒猫旅行 编辑:程序博客网 时间:2024/05/03 10:56

N久以前写的一个迭代加深和神奇剪枝的搜索,如今我竟然写不出来,悲哀啊!
出答案很简单,但是要AC要加各种神奇的优化,我都写在代码的注释中了啦。

#include<cstdio>#include<cmath>using namespace std;int best = 0xffffff,n,m,minv[25];void dfs(int i,int ri,int hi,int si,int vi)//剩余层数,上一层半径,上一层高度,当前表面积,剩余蛋糕体积{    if(i == 0)    {        if(si < best&&vi == 0) best = si;        return;    }    if(vi < minv[i]) return;//比至少剩的体积还小,做不成蛋糕    if(vi/(2*ri)+si > best) return;//剩余体积/(2*上一层半径) = 可能的最小侧面积,加上已经有的面积,还比最优解大,那么没有更优的解    for(int j = ri-1; j >= i; j--)    {        if(i == m) si = j*j;//最下一层的半径决定了上表面的面积        for(int k = hi-1; k >= i; k--)            dfs(i-1,j,k,si+2*j*k,vi-j*j*k);    }}int main(){    scanf("%d%d",&n,&m);    for(int i = 1; i <= m; i++)//至少剩余的体积,从上往下第i层的半径高度至少为i    {           minv[i] = minv[i-1] + i*i*i;    }    dfs(m,sqrt(n/m),n/(m*m),0,n);//体积/最小高度=最大底面积,开个根号就是最大地面半;体积/(最小底面积半径^2)=地面最大高度    if(best == 0xffffff)        printf("0\n");    else        printf("%d\n",best);}
0 0
原创粉丝点击