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];
}
}