bzoj 1024[SCOI2009]生日快乐 - DFS

1024: [SCOI2009]生日快乐

Time Limit: 1 Sec  Memory Limit: 162 MB

Description

  windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕。现在包括windy
,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋糕。windy主刀,每一切只能平行于一块蛋糕
的一边(任意一边),并且必须把这块蛋糕切成两块。这样,要切成 N 块蛋糕,windy必须切 N-1 次。为了使得
每块蛋糕看起来漂亮,我们要求 N块蛋糕的长边与短边的比值的最大值最小。你能帮助windy求出这个比值么?

Input

  包含三个整数,X Y N。1 <= X,Y <= 10000 ; 1 <= N <= 10

Output

  包含一个浮点数,保留6位小数。

Sample Input

5 5 5

Sample Output

1.800000
 
暴力DFS
因为我们发现最后切的蛋糕面积是确定的
因此我们可以枚举块数,这样切刀的位置也是确定的了,N很小,所以DFS随便搞
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <algorithm>
 6 #define LL long long
 7 
 8 using namespace std;
 9 
10 double ans = 1e9;
11 int kind[20];
12 int status[20];
13 vector<int> g[20][100];
14 double X, Y, N;
15 void split(int k, int sum, int num, int cnt)
16 {
17     if(sum > num) {
18         return;
19     }
20     if(sum == num) {
21         kind[num]++;
22         for(int i = 0; i < k; i++) {
23         //    cout<<status[i]<<" ";
24             g[num][kind[num]].push_back(status[i]);
25         }
26     //    cout<<endl;
27         return ;
28     }
29     for(int i = cnt; i < num; i++) {
30         status[k] = i;
31         split(k + 1, sum + i, num, i);
32     }
33 }
34 double cal(double x, double y, int n, int status) // status  = 0 表示 竖着切,  status = 1 表示 横着切 
35 {
36     if(n == 1) {
37         if(x < y) {
38             swap(x, y);
39         }
40         return x / y;
41     }
42     if(status == 0) { 
43         double minn = 1e9;
44         for(int i = 1; i <= kind[n]; i++) {
45             double maxn = -1e9;
46             for(int j = 0; j < g[n][i].size(); j++) {
47                 maxn = max(maxn, cal(x, y / n * g[n][i][j], g[n][i][j], 1));
48             }
49             minn = min(minn, maxn);
50         }
51         return minn;
52     } else {
53         double minn = 1e9;
54         for(int i = 1; i <= kind[n]; i++) {
55             double maxn = -1e9;
56             for(int j = 0; j < g[n][i].size(); j++) {
57                 maxn = max(maxn, cal(x / n * g[n][i][j], y, g[n][i][j], 0));
58             }
59             minn = min(minn, maxn);
60         }
61         return minn;
62     }
63 }
64 
65 inline LL read()
66 {
67     LL x = 0, w = 1; char ch = 0;
68     while(ch < '0' || ch > '9') {
69         if(ch == '-') {
70             w = -1;
71         }
72         ch = getchar();
73     }
74     while(ch >= '0' && ch <= '9') {
75         x = x * 10 + ch - '0';
76         ch = getchar();
77     }
78     return x * w;
79 }
80 
81 void init()
82 {
83     for(int i = 1; i <= 10; i++) { 
84         split(0, 0, i, 1);
85     }
86 }
87 
88 int main()
89 {
90     init();
91     X = read(), Y = read(), N = read();
92     ans = min(ans, cal(X, Y, N, 0));
93     ans = min(ans, cal(X, Y, N, 1));
94     printf("%.6lf\n", ans);
95     return 0;
96 }
View Code

 

posted @ 2018-02-13 16:18  大财主  阅读(81)  评论(0编辑  收藏