標題:測試次數
x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之后才允許上市流通。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之后才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
為了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高為1000層,如果我們總是采用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
請填寫這個最多測試次數。
注意:需要填寫的是一個整數,不要填寫任何多余內容。
令dp[i][j]為i層j個手機的最多(最優)測試次數。第一摔如何摔?每一層都可以作為第一摔。
設第一摔選在了第k層。
第一摔只能有兩種結果:碎或者不碎。
1)碎了,上面的層不再考慮,只需要在下面的層測試,手機少了一部,即 dp[k-1][j-1]
2) 沒碎,下面的層不再考慮,只需要在上面的層測試,手機還是那么多,即 dp[i-k][j]
因此,從k層開始摔,運氣最壞需要 max(dp[k-1][j-1], dp[i-k][j]) + 1 次測試
k有多種選擇,因此 最好的結果為: dp[i][j] = min( max(dp[k-1][j-1], dp[i-k][j]) + 1 ) for k in [1, i]
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int main() { 6 const int N = 1000, M = 3; 7 int dp[N+1][M+1] = {0}; 8 int _min; 9 10 for(int i=1; i<=N; i++) { 11 dp[i][1] = i; 12 } 13 for(int j=1; j<=M; j++) { 14 dp[1][j] = 1; 15 } 16 17 for(int i=2; i<=N; i++) { 18 for(int j=2; j<=M; j++) { 19 _min = max(1,dp[i-1][j]+1); // count at 1 floor, was as initial value 20 for(int k=1; k<=i; k++) { 21 _min = min( _min, max(dp[k-1][j-1],dp[i-k][j])+1 ); 22 } 23 dp[i][j] = _min; 24 } 25 } 26 cout<<dp[N][M]; 27 return 0; 28 } 29 // dp[i][j] = min( max(dp[k-1][j-1], dp[i-k][j]) + 1 ) for k in [1, i]
參考
