題目描述
x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。
塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
爲了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高爲1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
輸出
輸出一個整數表示答案
思路——動態規劃
動態規劃方程:f[i][j] i表示手機個數,j表示樓層數。
當i=1時 即每一個j層的樓房,我們都要摔j次,這其實就是最佳策略,那麼我們就可以逐漸往上擴展。
假設我們已經把i-1部手機對於所有的樓層的次數都已經找出來了,現在我們來求有i部手機時的測試次數。
爲此我們需要遍歷 當前之前的樓層k(1~j-1)假設在k層摔壞 我們就選取i-1部手機對於k-1層樓房的最壞情況dp[i-1][k-1]+1
假如在k層沒有摔壞 那麼我們就可以選取i部手機對於剩下j-k層的最壞情況 dp[i][j-k]+1
由於是最壞運氣 我們需要在兩者之間取最大值,但我們又是採取的最佳策略, 所以我們需要取最小值,即:
d[i][j]=min(dp[i][j],max(dp[i-1][k-1],dp[i][j-k])+1);
AC代碼
#include<bits/stdc++.h>
using namespace std;
int f[5][1005];
int main(){
for(int i=1;i<=3;i++){
for(int j=1;j<=1000;j++){
f[i][j]=j;
}
}
for(int j=1;j<=1000;j++){
for(int i=2;i<=3;i++){
for(int k=2;k<j;k++){
f[i][j]=min(f[i][j],max(f[i-1][k-1]+1,f[i][j-k]+1));
}
}
}
cout<<f[3][1000]<<endl;
return 0;
}