蓝桥杯——测试次数·摔手机(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];
	}
}
posted @ 2019-07-14 01:15  虎老狮  阅读(939)  评论(0编辑  收藏  举报