题目链接:http://poj.org/problem?id=1190点击打开链接
生日蛋糕
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 20099 | Accepted: 7153 |
Description
7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri, 高度为Hi的圆柱。当i < M时,要求Ri > Ri+1且Hi > Hi+1。
由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积Q最小。
令Q = Sπ
请编程对给出的N和M,找出蛋糕的制作方案(适当的Ri和Hi的值),使S最小。
(除Q外,以上所有数据皆为正整数)
Input
有两行,第一行为N(N <= 10000),表示待制作的蛋糕的体积为Nπ;第二行为M(M <= 20),表示蛋糕的层数为M。
Output
仅一行,是一个正整数S(若无解则S = 0)。
Sample Input
100 2
Sample Output
68
Hint
圆柱公式
体积V = πR 2H
侧面积A' = 2πRH
底面积A = πR 2
体积V = πR 2H
侧面积A' = 2πRH
底面积A = πR 2
Source
这题看得我蒙蒙的 数学差没办法
稍微模拟一下 暴搜就行
注意要对面积和体积同时剪枝
一开始只使劲减面积一直t
网上还有另外一种剪枝办法 不想研究了
row是当前层数(由下往上数) 而surplus为剩余体积
sum为已经确定的面积总和 rr hh为下一层的半径和高
注意总层数-当前层数要+1 因为当前层数还没确定
这个地方又wa了几次。。
#include <iostream>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <limits.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <math.h>
using namespace std;
int n,m;
int ans=INT_MAX;
int r;
int h;
void dfs(int row,int surplus,int sum,int rr,int hh)
{
if(row==(m)&&surplus==0)
{
if(ans>sum)
{
//cout << rr << endl;
//cout << hh<< endl;
ans=min(ans,sum);
}
return;
}
if(surplus>=(m-row+1)*(rr-1)*(rr-1)*(hh-1))
return ;
if((sum)>ans||surplus<0)
return;
for(int rrr=rr-1;rrr>=(m-row);rrr--)
{
for(int hhh=hh-1;hhh>=(m-row);hhh--)
{
sum=sum+2*rrr*hhh;
surplus-=(hhh*rrr*rrr);
dfs(row+1,surplus,sum,rrr,hhh);
sum=sum-2*rrr*hhh;
surplus+=(hhh*rrr*rrr);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(r=n;r>=1;r--)
{
if((r*r)>n)
continue;
for(h=n;h>=1;h--)
{
if(h*r*r>n)
continue;
dfs(1,n-r*r*h,r*2*h+r*r,r,h);
}
}
cout << ans;
}