1024: [SCOI2009]生日快乐
Time Limit: 1 Sec Memory Limit: 162 MBDescription
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 }