蓝桥杯——测试次数·摔手机(2018JavaB组第4题,17分)

x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。

如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n

为了减少测试次数,从每个厂家抽样3部手机参加测试。

某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

请填写这个最多测试次数。

注意:需要填写的是一个整数,不要填写任何多余内容。

通常会想到二分法,但是:1000层,500层,250层,……手机不够摔。

答案:19
package bb;
public class JB18_4测试次数_摔手机 {
    public static void main(String[] args) {
        int ret = testCount(1000, 3);
        System.out.println(ret);
    }
    public static int testCount(int floor, int phone) {
        if (phone == 1) {
            // 最后一部手机:一层一层地摔
            return floor;
        }
        // 之所以+1,是为了和题目接近,1楼开始,1部手机算起,不从0计数了
        int[][] arr动态规划 = new int[floor + 1][phone + 1];
        for (int i = 1; i != arr动态规划.length; i++) {
            arr动态规划[i][1] = i;
        }
        for (int n = 1; n < arr动态规划.length; n++) {
            // n:共多少层(1000层分为1~500,则n=500;再分为501~100,则n=500)
            for (int ph = 2; ph < arr动态规划[0].length; ph++) {
                // ph:手机数(1部手机时不管了,前面已经拦截了)
                int min = Integer.MAX_VALUE;
                for (int i = 1; i < n + 1; i++) {
                    // i:当前楼层——摔手机两种结果:要么摔坏了,要么没摔坏
                    int 摔坏 = arr动态规划[i - 1][ph - 1];// i-1层以下去摔,手机损失1部
                    int 没摔坏 = arr动态规划[n - i][ph];// i层以下排除,还有n-i层用于测试,手机数不变
                    // 题目要求:最坏的运气下最多需要测试多少次才能确定手机的耐摔指数
                    int 最坏运气次数 = Math.max(摔坏, 没摔坏);
                    // 题目要求:采用最佳策略
                    min = Math.min(min, 最坏运气次数);
                }
                arr动态规划[n][ph] = min + 1;
            }
        }
        return arr动态规划[floor][phone];
    }
}

蓝桥杯——测试次数·摔手机(2018JavaB组第4题,17分)

上一篇:Travis CI Could not find or load main class org.gradle.wrapper.GradleWrapperMain 错误


下一篇:【转载】 华为荣耀手机如何进入开发者模式