[SCOI2009]生日快乐
[SCOI2009]生日快乐
https://ac.nowcoder.com/acm/problem/20272
没看题解的时候实在是一头雾水不知从何下手
题意:
windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕。现在包括windy ,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋糕。
windy主刀,每一切只能平行于一块蛋糕 的一边(任意一边),并且必须把这块蛋糕切成两块。这样,要切成 N 块蛋糕,windy必须切 N-1 次。
为了使得每块蛋糕看起来漂亮,我们要求 N块蛋糕的长边与短边的比值的最大值最小。你能帮助windy求出这个比值么?
题解:
他要保证的是每块面积都要相同,所以我们在爆搜的时候只需要让他的面积保持不变即可,我们横着切和竖着切如果平均切k刀的话,最后每一块的面积是相同的。
每块的长最小为x/k,宽最小为y/k,每次切的长度-定是x/k或y/k的倍数。
至于为什么你分割的时候是除到k/2,这个是因为如果你除到小于k的话,这样就会有一半重复的内容,再加上这种指数级别的复杂度,可能在效率上就不是那么高了,所以除到k/2是防止重复计算的。
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <stdlib.h> const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 1e9 + 7; const int maxn=1e6+10; using namespace std; double dfs(double x,double y,int k){ if(k==1){ return max(x,y)/min(x,y); } double ans=1e18,minx=x/k,miny=y/k; for(int i=1;i<=k/2;i++){ double res1=max(dfs(minx*i,y,i),dfs(x-minx*i,y,k-i)); double res2=max(dfs(x,miny*i,i),dfs(x,y-miny*i,k-i)); ans=min(ans,min(res1,res2)); } return ans; } int main() { double x,y; int k; cin>>x>>y>>k; double ans=dfs(x,y,k); printf("%.6f\n",ans); return 0; }
题解 文章被收录于专栏
主要写一些题目的题解