[SCOI2009]生日快乐
作者:互联网
这道题最多只切9刀,然后爆搜就过了(这只是感性理解吧,复杂度我不太会算)。
怎么爆搜呢,首先,如果一个长为x,宽为y的蛋糕被分成k份,那么每一份长最小为x / k,宽最小为y / k,而且每一块蛋糕的长和宽都是这个数的整数倍,这个不难理解。
然后就可以爆搜了:对于每一个状态(x, y, k)枚举他被横着切的情况和纵着切的情况,也就是总共2 * k种,那横着切举例,分别比较切开的两种状态的比值,这么递归下去直到k == 1,此时返回max(x, y) / min(x, y)即可,然后取最大的,再在这些最大的中取最小的就是答案。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<stack> 10 #include<queue> 11 using namespace std; 12 #define enter printf("\n") 13 #define space printf(" ") 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const int eps = 1e-8; 19 //const int maxn = ; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) 26 { 27 ans = ans * 10 + ch - '0'; ch = getchar(); 28 } 29 if(last == '-') ans = -ans; 30 return ans; 31 } 32 inline void write(ll x) 33 { 34 if(x < 0) x = -x, putchar('-'); 35 if(x >= 10) write(x / 10); 36 putchar(x % 10 + '0'); 37 } 38 39 int x, y, n; 40 db dfs(db x, db y, int k) 41 { 42 if(k == 1) {return max(x, y) / min(x, y);} 43 db ans = (db)INF * (db)INF, tx = x / (db)k, ty = y / (db)k; 44 for(int i = 1; i <= (k >> 1); ++i) 45 { 46 db t1 = max(dfs(tx * i, y, i), dfs(x - tx * i, y, k - i)); //横向切 47 db t2 = max(dfs(x, ty * i, i), dfs(x, y - ty * i, k - i)); //纵向切 48 ans = min(ans, min(t1, t2)); 49 } 50 return ans; 51 } 52 53 int main() 54 { 55 x = read(); y = read(); n = read(); 56 printf("%.6lf\n", dfs(x, y, n)); 57 return 0; 58 }View Code
标签:ch,int,db,dfs,SCOI2009,ans,include,生日快乐 来源: https://blog.51cto.com/u_15234622/2830839