兩則面試題(動態規划)


某幢大樓有100層。你手里有兩顆一模一樣的玻璃珠。當你拿着玻璃珠在某一層往下扔的時候,一定會有兩個結果,玻璃珠碎了或者沒碎。這幢大樓有個臨界樓層。低於它的樓層,往下扔玻璃珠,玻璃珠不會碎,等於或高於它的樓層,扔下玻璃珠,玻璃珠一定會碎。玻璃珠碎了就不能再扔。現在讓你設計一種方式,使得在該方式下,最壞的情況扔的次數比其他任何方式最壞的次數都少。也就是設計一種最有效的方式。

例如:有這樣一種方式,第一次選擇在60層扔,若碎了,說明臨界點在60層及以下樓層,這時只有一顆珠子,剩下的只能是從第一層,一層一層往上實驗,最壞的情況,要實驗59次,加上之前的第一次,一共60次。若沒碎,則只要從61層往上試即可,最多只要試40次,加上之前一共需41次。兩種情況取最多的那種。故這種方式最壞的情況要試60次。仔細分析一下。如果不碎,我還有兩顆珠子,第二顆珠子會從N+1層開始試嗎?很顯然不會,此時大樓還剩100-N層,問題就轉化為100-N的問題了。

那該如何設計方式呢?

根據題意很容易寫出狀態轉移方程:N層樓如果從n層投下玻璃珠,最壞的嘗試次數是:clip_image002[6]

那么所有層投下的最壞嘗試次數的最小值即為問題的解:clip_image002[8]。其中F(1)=1.

/*
 *侯凱,2014-9-15
 *功能:100樓層拋珠問題
 */
#include<iostream>
using namespace std;

int dp[101];
//N<=100;
int floorThr(int N)
{
    for(int i=2;i<=N;i++)
    {
        dp[i]=i;
        for(int j=1;j<i;j++)
        {
            int tmp = max(j,1+dp[i-j]);
            if(tmp<dp[i])
                dp[i] = tmp;
        }
    }
    return dp[N];
}

int main()
{
    dp[0]=0;
    dp[1]=1;
    int dis = floorThr(100);
    cout<<dis<<endl;
    system("Pause");
}

輸出為14,說明在合適的樓層拋玻璃珠,最差情況下只需14次可找到臨界層。

答案是先從14樓開始拋第一次;如果沒碎,再從27樓拋第二次;如果還沒碎,再從39樓拋第三次;如果還沒碎,再從50樓拋第四次;如此,每次間隔的樓層少一層。這樣,任何一次拋棋子碎時,都能確保最多拋14次可以找出臨界樓層。

求最大子段積

問題定義:對於給定序列a1,a2,a3……an,尋找它的某個連續子段,使得其和最大。如( 1,2,3,4,0,5,4,-3,-2 )最大子段是{ 11,-4,13 }其和為20。既然是連續子串,當前的最大值只可能由前一位置的最大值(最小值)與當前值相乘得到,狀態轉移方程為:

clip_image002[10]

/*
 *侯凱,2014-9-15
 *功能:最大子串積
 */
#include<iostream>
using namespace std;

int bigestmult(int *a,int n)
{
    int *maxarrary = new int[n];
    int *minarrary = new int[n];
    maxarrary[0]=a[0];
    minarrary[0]=a[0];
    int res = a[0];
    for(int i=1;i<n;i++)
    {
        maxarrary[i] = max(max(maxarrary[i-1]*a[i],minarrary[i-1]*a[i]),a[i]);
        minarrary[i] = min(min(maxarrary[i-1]*a[i],minarrary[i-1]*a[i]),a[i]);
        if(maxarrary[i]>res)
            res = maxarrary[i];
    }
    delete [] maxarrary;
    delete [] minarrary;
    return res;
}

int main()
{
    int a[]={1,2,3,4,0,5,4,-3,-2};
    cout<<bigestmult(a,9)<<endl;
    system("Pause");
}

還有很多類似的問題,可參見:http://blog.csdn.net/liufeng_king/article/details/8490770,整理地非常完整。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM