生日蛋糕

题目背景

7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层

生日蛋糕,每层都是一个圆柱体。

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

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

令Q= Sπ

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

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

题目描述

输入输出格式

输入格式:

 

有两行,第一行为N(N<=20000),表示待制作的蛋糕的体积为Nπ;第二行为M(M<=15),表示蛋糕的层数为M。

 

输出格式:

 

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

 

输入输出样例

输入样例#1
100
2
输出样例#1: 
68

 

dfs+剪枝

 

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

inline int read()
{
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();}
    while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}

int n,m,ans=2e9,r[20],h[20];

void dfs(int x,int y,int k)
{
    if(k>ans) return ;
    if(x==m+1 && y==0)
    {
        k+=r[1]*r[1];
        ans=min(ans,k);
        return ;
    }
    if(k+m-x+1+r[1]*r[1]>ans) return ;//S
    if(y>r[x-1]*r[x-1]*h[x-1]*(m-x+1)) return ;//V
    for(int i=r[x-1]-1;i>=m-x+1;i--)
        for(int j=h[x-1]-1;j>=m-x+1;j--)
        {
            if(x+1<=m+1 && y-i*i*j>=0)
            {
                r[x]=i;
                h[x]=j;
                dfs(x+1,y-i*i*j,k+2*i*j);
                r[x]=0;
                h[x]=0;
            }
        }
}

int main()
{
    n=read(); m=read();
    r[0]=(int)sqrt(n);
    h[0]=(int)sqrt(n);
    dfs(1,n,0);
    if(ans==2e9) ans=0;
    printf("%d",ans);
    return 0;
}
这是代码

 

posted @ 2018-07-23 13:41  白驹过隙----青春绿  Views(201)  Comments(0Edit  收藏  举报