zoukankan      html  css  js  c++  java
  • 生日蛋糕

    生日蛋糕


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

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

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

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

    #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);
    }
    
  • 相关阅读:
    Git常用操作命令
    百度地图集成--二
    百度地图的集成--超详细
    iOS开发系列--地图与定位
    整理了一份React-Native学习指南(转)
    iOS高级编程之JSON,XML数据解析
    iOS开发基础
    C#001
    C#00
    英语学习tips
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9782195.html
Copyright © 2011-2022 走看看