摔手機
摔手機 動態規划 在藍橋杯的時候遇到一次 當時沒有做對 看了題解也沒明白 如今再次遇到這個類似的題目
於是拿出來補補吧
摔手機題目如下:
星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之后才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
為了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高為1000層,如果我們總是采用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
請填寫這個最多測試次數。
之前做題目時比較天真 覺得 二分 摔手機最優啦 ╮( ̄▽ ̄")╭ ╮( ̄▽ ̄")╭ 菜雞的天真
對於這個題目 我們也可以設計一個狀態 dp[i][j] i代表手機的數目 j代表層數 dp[i][j]為i個手機j層最佳的策略 最糟糕的次數
下面就是要去求 dp[i][j]是多少啦
假如這里有j層 那么我們可以選擇一層 第k層 把手機摔下去 當然 0<k<j
那么我們丟下去就有2種可能 一種是摔壞了 一種是沒有摔壞
摔壞了 那么我們就要從 這1到k-1層中去找 那么我們從第k層摔下去 摔壞了后 所需要的摔手機的次數 就是 dp[i-1][k-1]+1
如果沒有摔壞 我們就要從k+1到j這 j-k層中去找 那么我們從第k層摔下去 沒有摔壞后 所需要的摔手機的次數 就是 dp[i1][j-k]+1
因為是最糟糕的情況 所以我們要這兩種情況的最大值
但是k層能有好多種選擇 把k遍歷一遍 這這么一堆情況的最小值 那個最小值就是 dp[i][j] 即為 我們i個手機從第j層丟下去 測試那層摔壞的最優策略的最糟糕的次數
感覺比較繞繞的
可以使用遞推推出來 在遞推之前還要預處理一下 即1個手機 測試多少層 那么次數就多少層
一共1層 無論多少個手機 都是測試一次
一共0層 無論多少個手機 都是測試零次
代碼如下
int dp[51][1001];
memset(dp,0x3f,sizeof(dp));
於是拿出來補補吧
摔手機題目如下:
星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之后才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
為了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高為1000層,如果我們總是采用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
請填寫這個最多測試次數。
之前做題目時比較天真 覺得 二分 摔手機最優啦 ╮( ̄▽ ̄")╭ ╮( ̄▽ ̄")╭ 菜雞的天真
對於這個題目 我們也可以設計一個狀態 dp[i][j] i代表手機的數目 j代表層數 dp[i][j]為i個手機j層最佳的策略 最糟糕的次數
下面就是要去求 dp[i][j]是多少啦
假如這里有j層 那么我們可以選擇一層 第k層 把手機摔下去 當然 0<k<j
那么我們丟下去就有2種可能 一種是摔壞了 一種是沒有摔壞
摔壞了 那么我們就要從 這1到k-1層中去找 那么我們從第k層摔下去 摔壞了后 所需要的摔手機的次數 就是 dp[i-1][k-1]+1
如果沒有摔壞 我們就要從k+1到j這 j-k層中去找 那么我們從第k層摔下去 沒有摔壞后 所需要的摔手機的次數 就是 dp[i1][j-k]+1
因為是最糟糕的情況 所以我們要這兩種情況的最大值
但是k層能有好多種選擇 把k遍歷一遍 這這么一堆情況的最小值 那個最小值就是 dp[i][j] 即為 我們i個手機從第j層丟下去 測試那層摔壞的最優策略的最糟糕的次數
感覺比較繞繞的
可以使用遞推推出來 在遞推之前還要預處理一下 即1個手機 測試多少層 那么次數就多少層
一共1層 無論多少個手機 都是測試一次
一共0層 無論多少個手機 都是測試零次
代碼如下
int dp[51][1001];
memset(dp,0x3f,sizeof(dp));
for(int i=1;i<1001;i++)dp[1][i]=i;
for(int i=1;i<51;i++)dp[i][0]=0;
for(int i=1;i<51;i++)dp[i][1]=1;
for(int j=2;j<51;j++)
for(int j=2;j<51;j++)
for(int i=1;i<1001;i++){
for(int k=1;k<i;k++)
dp[j][i]=min(max(dp[j-1][k-1],dp[j][i-k])+1,dp[j][i]);
}
下面要幾個手機幾層樓 至少需要次數多少次 就好像一個表一樣 直接查詢就可以了
下面要幾個手機幾層樓 至少需要次數多少次 就好像一個表一樣 直接查詢就可以了