洛谷P1731 [NOI1999] 生日蛋糕dfs

题目描述

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

设从下往上数第 i(1≤i≤M)层蛋糕是半径为 Ri​,高度为 Hi​ 的圆柱。当 i<M 时,要求 Ri​>Ri+1​ 且 Hi​>Hi+1​。

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

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

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

输入格式

第一行为一个整数 N(N≤2×104),表示待制作的蛋糕的体积为 Nπ。

第二行为 M(M≤15),表示蛋糕的层数为 M。

输出格式

输出一个整数 S,若无解,输出 0。

输入输出样例

输入 #1

100
2

输出 #1

68

AC代码

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int n , m,v,sum[23] ;
int mxr,mxh ,ans = 2e9;
void dfs(int r ,int h, int pos ,int s,int v) //当前层的半径,高,层数,侧面积,体积
{
    s += 2* r* h;
    v += r* r* h;
    if(pos==1)
    {
        if(v==n) ans = min(ans,s);
        return ;
    }
    if(v>n) return;
    if( v+(pos-1)*(r-1)*(r-1)*(h-1) < n) return;
    if(s+sum[pos-1]>=ans) return;

    for(int i=r-1;i>=pos-1;--i)
        for(int j=h-1;j>=pos-1;--j)
        dfs(i,j,pos-1,s,v);
}
int main()
{

    scanf("%d %d",&n,&m);//体积  层数
    int tmp = n ;
    for(int i=1;i<m;++i)
    {
        tmp -= i*i*i;//剩下的是最大的下边的体积(第一排的体积)
        sum[i] = 2* i * i;
        sum[i] += sum[i-1];  // sum[i]表示i行之前(包括i行)的所有面积之和
    }
    if( tmp <m * m * m ) //tmp =  第1排最大的体积 < m*m*m 代表的是最小的体积(m代表的是最小的长度 )  G
    {
        cout<<0;
        return 0 ;
    }
    mxr  = sqrt(tmp/m);
    mxh  = tmp/(m*m);


        for(int i=mxr;i>=m;--i)
            for(int j=mxh;j>=m;--j)
                dfs(i,j,m,i*i,0);

    if(ans ==2e9 ) cout<<0<<endl;
    else cout<<ans<<endl;


    return 0 ;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值