P4160 题解

题意

将一个 \(X \times Y\) 矩形切成 \(N\) 份,且必须切 \(N-1\) 次,求切完的矩形的长宽比的最大值最小。

思路

每次横切或纵切,将矩形分成相等的 \(K\) 份。切了一刀后,第一块的面积为原来的 \(\frac {i}{K}\),第二块的面积为原来的\(\frac {K-i}{K}\)。然后继续递归,将 第一块 蛋糕分为 \(i\) 块,第二块分为 \(K-i\) 块,保证最大值最小即可。

切到最后,即 \(K=1\) 时,\(S\) 一定相等。

代码(对拍用)

#include <bits/stdc++.h>

#ifdef LOCAL
#define Debug(x) std::cout << "$ Debug(" << #x << ") = " << x << "\n"
#else
#define Debug(x)
#endif

#define STACK_SIZE 32
namespace OI {

	bool f;
	char ch;
	
	template <class T>
	void read(T &x) {
		x = f = 0;
		ch = getchar();
		while (ch < '0' || ch > '9') {
			if (ch == '-') f = true;
			ch = getchar();
		}
		while (ch >= '0' && ch <='9')
			x = x * 10 + ch - 48,
			ch = getchar();
		if (f) x = -x;
	}
	
	int top, stack[STACK_SIZE];
	template <class T>
	void _write(T x) {
		top = 0;
		do {
			stack[top++] = x % 10, x /= 10;
		} while(x);
		while (top) putchar(stack[--top] + '0');
	}
	
	template <class T>
	void write(T x) {
		if (x < 0) x = -x, putchar('-');
		_write<T>(x);
	}
	
	template <class T>
	inline T abs(T x) { return x < 0 ? -x : x; }
	template <class T>
	inline T min(T x, T y) { return x < y ? x : y; }
	template <class T>
	inline T max(T x, T y) { return x > y ? x : y; }
}
using OI::read;
using OI::write;

double dfs(double n, double m, double k) 
{
	if (k == 1)
		return OI::max(n, m) / OI::min(n, m);
	double mn = 0x3f3f3f;
	for (int i = 1; i <= k / 2.0; ++i)
		mn = OI::min(
			mn, 
			OI::min(
				OI::max(dfs(n / k * i, m, i), dfs(n - n / k * i, m, k - i)), // 横着切
				OI::max(dfs(n, m / k * i, i), dfs(n, m - m / k * i, k - i)) // 竖着切
			) // 最大值最小
		);
	return mn;
}
int main() {
	int n, m, k;
	read(n); read(m); read(k);
	return printf("%.6lf", dfs(n, m, k)), 0;
}
posted @ 2021-12-07 22:07  _Return  阅读(100)  评论(1编辑  收藏  举报