题目背景
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:
这是代码
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; }