某幢大樓有100層。你手裡有兩顆一模一樣的玻璃珠。當你拿著玻璃珠在某一層往下扔的時候,一定會有兩個結果,玻璃珠碎了或者沒碎。這幢大樓有個臨界樓層。低於它的樓層,往下扔玻璃珠,玻璃珠不會碎,等於或高於它的樓層,扔下玻璃珠,玻璃珠一定會碎。玻璃珠碎了就不能再扔。現在讓你設計一種方式,使得在該方式下,最壞的情況扔的次數比其他任何方式最壞的次數都少。也就是設計一種最有效的方式。
例如:有這樣一種方式,第一次選擇在60層扔,若碎了,說明臨界點在60層及以下樓層,這時只有一顆珠子,剩下的只能是從第一層,一層一層往上實驗,最壞的情況,要實驗59次,加上之前的第一次,一共60次。若沒碎,則只要從61層往上試即可,最多只要試40次,加上之前一共需41次。兩種情況取最多的那種。故這種方式最壞的情況要試60次。仔細分析一下。如果不碎,我還有兩顆珠子,第二顆珠子會從n+1層開始試嗎?很顯然不會,此時大樓還剩100-n層,問題就轉化為100-n的問題了。
那該如何設計方式呢?
根據題意很容易寫出狀態轉移方程:n層樓如果從n層投下玻璃珠,最壞的嘗試次數是:
那麼所有層投下的最壞嘗試次數的最小值即為問題的解:
。其中f(1)=1.
/*輸出為14,說明在合適的樓層拋玻璃珠,最差情況下只需14次可找到臨界層。*侯凱,2014-9-15
*功能:100樓層拋珠問題 */
#include
using
namespace
std;
int dp[101
];//
n<=100;
int floorthr(int
n) }
return
dp[n];
}int
main()
答案是先從14樓開始拋第一次;如果沒碎,再從27樓拋第二次;如果還沒碎,再從39樓拋第三次;如果還沒碎,再從50樓拋第四次;如此,每次間隔的樓層少一層。這樣,任何一次拋棋子碎時,都能確保最多拋14次可以找出臨界樓層。
求最大子段積
問題定義:對於給定序列a1,a2,a3……an,尋找它的某個連續子段,使得其和最大。如( 1,2,3,4,0,5,4,-3,-2 )最大子段是其和為20。既然是連續子串,當前的最大值只可能由前一位置的最大值(最小值)與當前值相乘得到,狀態轉移方程為:
/*還有很多類似的問題,可參見:整理地非常完整。*侯凱,2014-9-15
*功能:最大子串積 */
#include
using
namespace
std;
int bigestmult(int *a,int
n) delete maxarrary;
delete minarrary;
return
res;
}int
main()
; cout
<9)<
system(
"pause");
}
360筆試題兩則
記憶深刻的兩道題 1.如下程式的輸出是什麼 解釋一下 基類指標指向子類物件,c 按照先基類後子類的方式建立物件,在構造基類物件的過程中呼叫基類構造方法,這個時候虛函式表還沒有被子類虛函式指標替換,呼叫的還是基類物件的函式。於是輸出兩個base。之後輸出兩個子類物件呼叫的方法。析構的時候由於基類物件的...
面試題,硬幣 動態規劃
題目描述 給定數量不限的硬幣,幣值為25分 10分 5分和1分,編寫 計算n分有幾種表示法。結果可能會很大,你需要將結果模上1000000007 示例1 輸入 n 5 輸出 2 解釋 有兩種方式可以湊成總金額 5 55 1 1 1 1 1 示例2 輸入 n 10 輸出 4 解釋 有四種方式可以湊成總...
LeetCode動態規劃 面試題17 16按摩師
乙個有名的按摩師會收到源源不斷的預約請求,每個預約都可以選擇接或不接。在每次預約服務之間要有休息時間,因此她不能接受相鄰的預約。給定乙個預約請求序列,替按摩師找到最優的預約集合 總預約時間最長 返回總的分鐘數。注意 本題相對原題稍作改動 示例 1 輸入 1,2,3,1 輸出 4 解釋 選擇 1 號預...