【OI做題記錄】【BZOJ】【SCOI2009】生日快樂
阿新 • • 發佈:2019-02-06
試題編號:BZOJ1024
windy的生日到了,為了慶祝生日,他的朋友們幫他買了一個邊長分別為 X 和 Y 的矩形蛋糕。現在包括windy,一共有 N 個人來分這塊大蛋糕,要求每個人必須獲得相同面積的蛋糕。windy主刀,每一切只能平行於一塊蛋糕
的一邊(任意一邊),並且必須把這塊蛋糕切成兩塊。這樣,要切成 N 塊蛋糕,windy必須切 N-1 次。為了使得
每塊蛋糕看起來漂亮,我們要求 N塊蛋糕的長邊與短邊的比值的最大值最小。你能幫助windy求出這個比值麼?
輸入描述
包含三個整數,X Y N。1 <= X,Y <= 10000 ; 1 <= N <= 10輸出描述
包含一個浮點數,保留6位小數。
輸入樣例
5
5 5
輸出樣例
1.800000
試題分析
好久沒有1A了,好開心啊!
①演算法確定 求最小值,這種求極值的題目,大概有幾個思路:DP,貪心,純模擬。 由於N非常的小,所以好像純模擬可以做,確切的說,用深搜。 ②演算法結構 我們發現,既然要分的蛋糕,面積相同,且分的方式只能垂直或者平行。深搜的拓展方式就比較少了。 對於一塊x*y的蛋糕,分成K份,每份的面積是確定的,那麼分的方式就有兩種: 這種情況可以將這個圖再分成兩部分,進行深搜左部分再分成三份,右部分分成K-3分 另一種分法:
③演算法細則
#include<cstdio>
#include<cstdlib>
#include<cstring>
int x,y,n;
double mymax(double x,double y)
{
return x>y?x:y;
}
double mymin(double x,double y)
{
return x<y?x:y;
}
double done(double x,double y,int n)
{
if(n==1)return mymax(x,y)/mymin(x,y);
double ans=999999999999;
for(int i=1;i<n;i++)
{
double xx=mymax(done(x,y/n*i,i),done(x,y/n*(n-i),n-i));
double yy=mymax(done(x/n*i,y,i),done(x/n*(n-i),y,n-i));
ans=mymin(ans,mymin(xx,yy));
}
return ans;
}
int main()
{
scanf("%d %d %d",&x,&y,&n);
printf("%.6lf",done(x,y,n));
}