zoukankan      html  css  js  c++  java
  • Acwing 168 生日蛋糕 (dfs+剪枝)

    题面

    7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。

    设从下往上数第i层蛋糕是半径为Ri, 高度为Hi的圆柱。

    当i < M时,要求Ri > Ri+1且Hi > Hi+1。

    由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。

    令Q = Sπ ,请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。

    除Q外,以上所有数据皆为正整数 。

    输入格式
    输入包含两行,第一行为整数N(N <= 10000),表示待制作的蛋糕的体积为Nπ。

    第二行为整数M(M <= 20),表示蛋糕的层数为M。

    输出格式
    输出仅一行,是一个正整数S(若无解则S = 0)。

    数据范围
    1≤N≤10000,
    1≤M≤20
    输入样例:
    100
    2
    输出样例:
    68

    思路

    这个题目的思路很明确,从下往上递归每一层,到最上面的时候结束递归。大概可以想到我们在dfs里面需要枚举的是一个每层蛋糕的r和h,那么r和h的范围是我们要确定的第一个点,首先体积限制和面积限制是我们要考虑的点,根据这两个我们可以推出r和h的范围,然后我们考虑最小的放蛋糕的情况,就是每次之比下面的半径和高度小1,然后利用这个条件进行剪枝。最后我们有一个最重要的剪枝,需要推导一下不等式,计算一下剩余体积最大和面积最大的限制,进行一个比较然后形成一个放缩不等式,进行一个最优化剪枝。总结一下搜索剪枝类问题的顺序,就是先开始最重要的是建立搜索模型或者说清楚搜索步骤,大概知道dfs函数里面的参数,并且知道递归结束的return怎么写,然后我们考虑优化一些搜索顺序,可行性剪枝,最优化剪枝等一一系列剪枝技巧。

    代码实现

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #include<vector>
    #include<cstring>
    #include<map>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef pair <int ,int> PII;
    const int maxn=20;
    const int inf=0x3f3f3f3f;
    int n,m;
    int mins[maxn],minv[maxn];
    int R[maxn],H[maxn],ans=inf;
    
    void dfs (int u,int v,int s) {
        if (v+minv[u]>n) return ;
        if (s+mins[u]>ans) return ; 
        if (s+2*(n-v)/R[u+1]>=ans) return;
    
        if (!u) {
            if (n==v) ans=s;
            return ;
        }
    
        for (int r=min ((int )sqrt (n-v),R[u+1]-1);r>=u;r--) 
          for (int h=min ((n-v)/r/r,H[u+1]-1);h>=u;h--) {
              int t=0;
              if (u==m) t=r*r;
              R[u]=r,H[u]=h;
              dfs (u-1,v+r*r*h,s+2*r*h+t);
          }
    }
    
    int main () {
        cin>>n>>m;
        for (int i=1;i<=m;i++) {
            minv[i]=minv[i-1]*i*i*i;
            mins[i]=minv[i-1]*i*i*2;
        }
        R[m+1]=H[m+1]=inf;
        dfs (m,0,0);
        if (ans==inf) cout<<0<<endl;
        else cout<<ans<<endl;
        return  0;
    }
    
  • 相关阅读:
    【Java123】javapoet代码生成代码工具
    【Python123】OptionParser初使用
    【Spring123】JdbcTemplate初使用 以及 ORA-01858: a non-numeric character was found where a numeric was expected, ORA-00911: invalid character解决
    【Java123】解决javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    git常用命令
    在虚拟机上搭建自己的 git 服务器并创建 git 仓库
    git用法
    Golang gRPC框架3-自签证书验证
    go _nsq
    mysql的备份和恢复
  • 原文地址:https://www.cnblogs.com/hhlya/p/13342108.html
Copyright © 2011-2022 走看看