生日蛋糕

本文探讨了如何通过算法解决生日蛋糕的制作问题,利用剪枝技术优化搜索过程,通过体积与面积之间的数学关系,有效地减少了计算量。文章详细解释了剪枝策略,并提供了具体的代码实现。

生日蛋糕


赤果果的搜索题。
恩,好题。
对于剪枝来说,我们可以使用最优情况进行剪枝,即是:使用最优情况+现在的情况与得到的答案进行比较
类似于估价函数的简单实现

然后对于这个题,我们可以寻找体积与面积之间的联系,利用不等式进行剪枝

$S_{\text{剩余}}=\sum^{m}_{i=\text{剩余层数}} ~~~~~R_i \cdot 2 \cdot H_i $
\(V_{\text{剩余}}=\sum^{m}_{i=\text{剩余层数}}~~~~~R_I^2 \cdot H_i\)
对于\(V_{\text{剩余}}\),有\(\frac{V_{\text{剩余}} \cdot 2}{R_{\text{当前层}}} <= S_{\text{剩余}}\)

所以,我们可以根据上述式子进行剪枝

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using std::min;
const int M=16;
int n,m;
int r[M],S[M],V[M],h[M];
int ans=0x7fffffff;
void dfs(int Vol,int sum,int now,int R,int H)//Vol:当前体积,sum:当前面积,now当前层数(自上而下),R:当层的最大半径,H同理
{
    if(now==0)//终止条件
    {
        if(Vol==n)
            ans=min(ans,sum);
        return ;
    }
    if(sum+S[now]>=ans) return ;//最优情况剪枝
    if(Vol+V[now]>n)   return ;//最优情况剪枝
    if(2*(n-Vol)/R+sum>=ans)  return ;//根据两者之间的关系剪枝
    for(int i=R;i>=r[now];i--)
    {
        if(now==m)  sum=i*i;//如果是底层,加上顶部面积
        int NxtH=min(H,(n-Vol-V[now-1])/(i*i));//根据上面蛋糕的最优情况,计算当前层的最高的高度
        for(int j=NxtH;j>=h[now];j--)//枚举
            dfs(Vol+i*i*j,sum+i*2*j,now-1,i-1,j-1);//emmmm
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        r[i]=i,h[i]=i;
    for(int i=1;i<=m;i++)
        S[i]=S[i-1]+r[i]*2*h[i];
    for(int i=1;i<=m;i++)
        V[i]=V[i-1]+r[i]*r[i]*h[i];
    dfs(0,0,m,28,28);
    if(ans==0x7fffffff) ans=0;
    printf("%d",ans);
}

转载于:https://www.cnblogs.com/Lance1ot/p/9782195.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值