1. 程式人生 > >8416: 生日快樂---入門dfs

8416: 生日快樂---入門dfs

8416: 生日快樂

時間限制: 1 Sec  記憶體限制: 128 MB
提交: 61  解決: 34
[提交] [狀態] [討論版] [命題人:admin]

題目描述

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

來源/分類

四川OI2009 

 

 

太菜,一開始沒想到dfs,後來覺得可以爆搜一下,但是還是不太清楚怎麼寫,

再後來,晚上睡覺做夢給解出來了

 

這個蛋糕不管怎麼說,肯定是一刀切兩半,那麼,

對於這兩半,肯定進行和第一步一樣的切,直到切不動了(面積等於要分的面積,即s=x*y/n)

假設咯,

先假設豎著切

|||||||||||||||||||||*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

|||||||||||||||||||||*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

|||||||||||||||||||||*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

|||||||||||||||||||||*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

|||||||||||||||||||||*|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

那麼,一共分n份,假設左邊k份,那麼,容易算出分割點吧

/*

設s=1.0*x*y/n(每一塊的面積),那麼左邊k塊,面積就是k*s,

設橫著w,豎著l,那左邊豎直高度不變,還是l,但是橫著w變成了k*s/l(l  *   k*s/l = k*s)

另一邊同理

*/

那麼橫著切也是一樣的分割,最後分出來後取最大值的最小值就好

 

兩個寫法

1,不管長和寬,在最後max一下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
int n,x,y;
double s;
double dfs(double l,double w,int k){
    if(k==1)
        return max(w/l,l/w);
    double ans = 1e10;
    for(int i=1;i<k;i++){
        double tans = max(dfs(w,i*s/w,i),dfs(w,(k-i)*s/w,k-i));
        ans = min(ans,tans);
        tans = max(dfs(l,i*s/l,i),dfs(l,(k-i)*s/l,k-i));
        ans = min(ans,tans);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&x,&y);
    scanf("%d",&n);
    s = 1.*x*y/n;
    printf("%.6f\n",dfs(1.*max(x,y),1.*min(x,y),n));
    return 0;
}

2,每一步控制長和寬,即dfs第一個引數一定是長邊,第二個。。。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
int n,x,y;
double s;
double dfs(double l,double w,int k){
    if(k==1){
        return l/w;
    }
    double ans = 1e10;
    for(int i=1;i<k;i++){
        double tans = 0;
        tans = max(tans,dfs(max(w,i*s/w),min(w,i*s/w),i));
        tans = max(tans,dfs(max(w,(k-i)*s/w),min(w,(k-i)*s/w),k-i));
        ans = min(ans,tans);
        tans = 0;
        tans = max(tans,dfs(max(l,i*s/l),min(l,i*s/l),i));
        tans = max(tans,dfs(max(l,(k-i)*s/l),min(l,(k-i)*s/l),k-i));
        ans = min(ans,tans);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&x,&y);
    scanf("%d",&n);
    s = 1.*x*y/n;
    printf("%.6f\n",dfs(1.*max(x,y),1.*min(x,y),n));
    return 0;
}