每日一題---摔手機

x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n。
爲了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高爲1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
請填寫這個最多測試次數。注意:需要填寫的是一個整數,不要填寫任何多餘內容。
題解:
這題適用dp來做。。最壞運氣即手機全部都摔壞了,才測出耐摔指數;最佳策略即儘量減少測試次數。

#include<bits/stdc++.h>
#define loop(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
int dp[5][1005];
int solve(int phone,int floor){
    //初始化,第i部手機在第j層摔壞的最壞層數爲j
    loop(i,1,phone)
        loop(j,1,floor){
            dp[i][j]=j;
        }
    loop(j,2,phone){
        loop(k,1,floor){
            loop(i,1,k-1){
                //這裏的DP的遞推公式爲f[j][k]=1+max(f[j-1][i-1],f[j][k-i]) i屬於[1,k-1]
                //在1~k層中隨機挑出一層i
                //如果第一部手機在第i層碎了,那麼將測試1~i-1就可以找出耐摔指數,即f[1][i-1]
                //如果第一部手機在第i層沒有碎,那麼將測試i+1~k層便可以找出耐摔指數,即k-i層
                //有j部手機,在已知i層不碎的情況下,測試1~i-1和i+1~k層的方法沒有區別,所以可以寫成f[j][i-1]+1
                //+1表示在在那層已經測過
                dp[j][k]=min(dp[j][k],1+max(dp[j-1][i-1],dp[j][k-i]));
                //int num1=dp[j-1][i-1];
                //int num2=dp[j][k-i];
                //int temp=max(num1,num2);
                //dp[j][k]=min(dp[j][k],1+temp);
            }
        }
    }
    return dp[phone][floor];
}
int main(){
    cout<<solve(3, 1000);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章