递归
数据范围较小,直接递归解决。
考虑将当前蛋糕分成left块:
当left==1时,返回长与宽的比值;
当left>1时,若沿着当前蛋糕的某一条边切割总共有n/2种切割方法(考虑对称性),沿着长和宽总共有(n/2)*2种切割方法;对于当前蛋糕的每一种切割方法,递归考虑其切割后的两个蛋糕,得到二者切割后能够生成的小蛋糕中长宽比值最大者(从一种切割方法生成的n块蛋糕中找到长宽比值最大的一块);对于当前蛋糕的所有切割方法,从中选出每种比值最大的小蛋糕的最小比值,返回该比值。
值得注意的是,对于递归中生成的所有最小蛋糕,不能一味取其最大比值或最小比值;要分清楚递归过程中,哪些步骤是在选择切分方法(取最小),哪些步骤是在切分(取最大)。
代码:
#include <iostream> #include <queue> #include <set> #include <map> #include <vector> #include <stack> #include <cmath> #include <algorithm> #include <cstdio> #include <cctype> #include <functional> #include <string> #include <cstring> #include <sstream> #include <deque> #define fir first #define sec second using namespace std; typedef long long ll; typedef pair<int,int> P; typedef pair<P,int> Q; const int inf1=2e9+9; const ll inf2=8e18+9; const ll mol=11e9+7; const int maxn=1e5+9; const ll maxx=1e12+9; int x,y,n; double arc; double dfs(int left,double a,double b) { if(a>b) swap(a,b); if(left==1) return b/a; double tmp=inf1; double la=arc/a,lb=arc/b; for(int i=1;i<=left/2;i++) tmp=min(tmp,max(dfs(i,la*i,a),dfs(left-i,b-la*i,a))); for(int i=1;i<=left/2;i++) tmp=min(tmp,max(dfs(i,lb*i,b),dfs(left-i,a-lb*i,b))); return tmp; } int main() { scanf("%d%d%d",&x,&y,&n); arc=x*y*1.0/n; printf("%.6lf\n",dfs(n,x,y)); }