标签:最小 无法 规划 ble win 划算 ++ acm amp
你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。
每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去,如果没有碎可以继续使用。
你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。
每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。
你的目标是确切地知道 F 的值是多少。
无论 F 的初始值如何,请你确定 F 的值的最小移动次数是多少?
例如:
输入:K = 1, N = 2 输出:2
输入:K = 2, N = 100 输出:14
输入:K = 3, N = 14 输出:4
(动态规划)$O(K\!N)$
注意:在鸡蛋没摔碎时,我们还能用这$i$个鸡蛋在在上面的$j-s$层确定$F$,这里的实验与在第$1~(j-w)$所需的次数是一样的,因为它们的实验方法和步骤都是相同的,只不过这$(j-w)$层在上面罢了。
时间复杂度
C++代码
1 class Solution { 2 public: 3 int superEggDrop(int K, int N) { 4 int m = K, n = N; 5 const int maxn = 100 + 10; 6 const int maxm = 10000 + 10; 7 int d[maxn][maxm]; //dp[i][j]表示有i颗鹰蛋在j层楼的最少次数 8 if (m >= ceil(log(n + 1) * 1.0) / log(2.0)) 9 return (int)ceil(log((n + 1) * 1.0) / log(2.0)); 10 else 11 { 12 memset(d, 0, sizeof(d)); 13 for (int i = 1; i <= n; i++) d[1][i] = i; 14 for (int i = 2; i <= m; i++) 15 { 16 int s = 1; 17 for (int j = 1; j <= n; j++) 18 { 19 d[i][j] = d[i][j - 1] + 1; // 20 21 while (s < j && d[i - 1][s] < d[i][j - s - 1]) s++; 22 23 d[i][j] = min(d[i][j], max(d[i - 1][s - 1], d[i][j - s]) + 1); 24 if (s < j) d[i][j] = min(d[i][j], max(d[i - 1][s], d[i][j - s - 1]) + 1); 25 } 26 } 27 return d[m][n]; 28 } 29 } 30 };
(动态规划)$O(KlogN)$
时间复杂度
C++代码
1 class Solution { 2 public: 3 int superEggDrop(int K, int N) { 4 vector<int> f(K + 1, 1); 5 f[0] = 0; 6 int m = 1; 7 while (f[K] < N) { 8 for (int i = K; i >= 1; i--) 9 f[i] = f[i] + f[i - 1] + 1; 10 m++; 11 } 12 13 return m; 14 } 15 };
在URAL OJ上也有这题,只是数据范围有所不同:Chernobyl’ Eagle on a Roof
参考链接:
1、https://www.acwing.com/solution/leetcode/content/579/
2、朱晨光:《优化,再优化!——从《鹰蛋》一题浅析对动态规划算法的优化
标签:最小 无法 规划 ble win 划算 ++ acm amp
原文地址:https://www.cnblogs.com/lfri/p/10350092.html