题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
X 星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
X 星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的 2 楼。
如果手机从第 7 层扔下去没摔坏,但第 8 层摔坏了,则手机耐摔指 =7。 特别地,如果手机从第 1 层扔下去就坏了,则耐摔指数 =0。 如果到了塔的最高层第 n 层扔没摔坏,则耐摔指数 =n。
为了减少测试次数,从每个厂家抽样 3 部手机参加测试。
某次测试的塔高为 1000 层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
请填写这个最多测试次数。
运行限制
- 最大运行时间:1s
- 最大运行内存: 128M
这道题千万不要第一眼可能上去就用二分log2N去求解,得到的结果是10,这个结果确确实实是错的,她并不满足二分的条件,我们转换一个思路
* 解题思路
首先我们看题目要求,在最坏的运气下这句话指的是什么意思呢,假如我们这栋楼有10层,我随便挑了第三层扔下手机,
* 如果这个手机摔碎了
则我们最多还要进行3-1=2次
* 如果这个手机没有碎
则我们需要向上向更高的楼层进行测试,则我们就最多还要进行10-3=7次
运气最坏就是指我们这两种情况中要进行可能测试次数最多的那种情况,假设我们当先仍手机的层数是K层,我们有i个手机,这个楼总共j层,设dp[i][j]代表i部手机,楼层有j层时的最佳策略则我们就可以总结出此时的状态转移方程为,Max(dp[i-1][k-1],dp[i][j-k])+1;
那我们整理一下思路,我们在j层楼时,我们可能仍手机的位置为1-j层,所以我们要求的最佳策略为这所有可能仍手机的层数对应的次数中最小的那次,所以我们得到了最终的状态转移方程
dp[i][j] = Min(dp[i][j],Max(dp[i-1][k-1],dp[i][j-k])+1);
但有一种特殊情况,当我们只有一部手机时,我们要采取保守策略,从最底层开始测起,则每一层可能的测试次数就等于上一层的测试次数加一,也就是dp[i][j] = dp[i][j-1]+1;所以状态转移方程为:
* 完整代码
public class Main {
public static void main(String[] args) {
System.out.println(searchResult());
}
public static int searchResult() {
int[][] dp = new int[4][1001];
for(int i = 1;i<=1000;i++)
dp[1][i] = i;
for(int j = 1;j<=1000;j++) {//楼层数
for(int i = 2;i<=3;i++) {//手机数
dp[i][j] = Integer.MAX_VALUE;
for(int k = 1;k<=j;k++)
dp[i][j] = Math.min(dp[i][j], Math.max(dp[i-1][k-1], dp[i][j-k])+1);
}
}
return dp[3][1000];
}
}