1. 程式人生 > >BZOJ 1024:[SCOI2009]生日快樂【DFS】

BZOJ 1024:[SCOI2009]生日快樂【DFS】

1024:[SCOI2009]生日快樂

Time Limit 1 Sec Memory Limit 162 MB

【題目描述】

  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

【解題報告】

這題第一眼看上去就是DP,可是我們會發現N很小,所以完全可以DFS求解。因為我們要切出相等的面積,所以就可以列舉當前切一刀,左邊將被切成i塊,右邊將被切成N-i塊(相應的左邊的x或y變成x/N*i或y/N*i,右邊x或y變成N-x/N*i或N-y/N*i),然後,最後可以保證切出的面積相等。
然後。。。
就解完了。

下面是我的程式碼:

#include<cstdio>
#include<iostream>
using namespace std;
double x,y;int n;
double DFS(double x,double y,int n){
    if(x<y) swap(x,y);//保證長大於寬 
    if(n==1) return x/y;//算出代價 
    double ans=1e99;
    for(int i=1;i<n;i++)
    ans=min(ans,max(DFS(x,y/n*i,i),DFS(x,y-y/n*i,n-i))),//豎著切 
    ans=min(ans,max(DFS(x/n*i,y,i),DFS(x-x/n*i,y,n-i)));//橫著切 
return ans;//返回代價 } int main(){ cin>>x>>y>>n; printf("%.6lf",DFS(x,y,n)); return 0; }

o(^ w ^)o