题目描述
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
请填写这个最多测试次数。
注意:需要填写的是一个整数,不要填写任何多余内容。
代码
/** * @author Fancier * @version 1.0 * @description: 测试次数 * @date 2024/3/11 9:08 */
public class Main { public static void main(String[] args) { int n, m; n = 1000; m = 3; int[][] dp = new int[n + 1][m + 1]; for (int i = 1; i <= n; i++) { dp[i][1] = i; } for (int j = 2; j <= m; j++) { for (int i = 1; i <= n; i++) { dp[i][j] = dp[i][j - 1]; for (int k = 2; k <= i; k++) { dp[i][j] = Math.min(dp[i][j], Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1); } } } System.out.println(dp[n][m]); }
}}
}
题解
思考
如果有3台手机从有1000层楼, 那从哪一层开始最合适呢
假设, 是从第k层, 在k层楼开始有两种状态 摔坏了 和 没摔坏
如过摔坏了, 应该从第几层开始呢? 这种情况相当于有两台手机有k - 1层
没摔坏又应该从第几层开始呢? 这种情况相当于有3台手机有 1000 - k层
应为运气差所以我们只会选择到这两种情况种对应测试次数多的一种(情况A)
这样我们又可以从带着同样的思维, 想情况A该从哪一层开始
如此循环, 知道触碰到边界情况为止 只有一台手机的情况 开始
说到这一步了, 那就很容易想到用动态规划来做了
dp[i][j] 对应有j台手机, 有i层的情况
状态转移方程
dp[i][j] = Math.max(dp[k - 1][j - 1], dp[i - k][j]) + 1;
如何确定这个k呢
遍历 找到使dp[i][j] 最小的k
dp[i][j] = Math.min(dp[i][j], Math.max(dp[k - 1][n - k], dp[i - k][j]) + 1);
填表顺序
从左往右, 从上到下
初始化
只有一台手机的情况, 我们只能一层一层的测试, 所以最坏情况就是楼层总数
for (int i = 1; i <= n; i++) { dp[i][1] = i;
}
具体代码参上
好的!本次分享到这就结束了
如果对铁汁你有帮助的话,记得点赞👍+收藏⭐️+关注➕
我在这先行拜谢了:)
其它解法推荐
o(1)时间复杂度的解法