POJ1190 生日蛋糕(DFS)

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);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值