動態規劃(2)

接下來就是一些常見的動態規劃題目:

(1)

對於兩個字符串A和B,我們需要進行插入、刪除和修改操作將A串變爲B串,定義c0,c1,c2分別爲三種操作的代價,請設計一個高效算法,求出將A串變爲B串所需要的最少代價。

給定兩個字符串AB,及它們的長度和三種操作代價,請返回將A串變爲B串所需要的最小代價。保證兩串長度均小於等於300,且三種代價值均小於等於100。

測試樣例:
"abc",3,"adc",3,5,3,100
返回:8
題目分析: 這是標準的動態規劃題目。建立dp[n+1][m+1]數組。dp[i][j]表示字符串A[0,1,2....i]到B[0,1,2...j]的變換所用的最小代價。dp[0][i]與dp[j][0]則是表示A空字符串變成B字符串的代價和A字符串變成空串的代價。說明多加了一行和一列且都爲空字符。則對於任意的一點(i,j)。其dp[i][j]的式子由下面的情況決定

    (1)當A[i-1]==B[j-1]時,說明(i,j)這個點的值,來自下面的三個方向(i-1,j),(i,j-1),(i-1,j-1)。如圖:

   

   則dp[i][j]等於dp[i-1][j-1] ,dp[i-1][j]+c1,dp[i][j-1]+c0中的最小值

(2)A[i-1]!=B[j-1]時:

   則dp[i][j]等於dp[i-1][j-1] +c2,dp[i-1][j]+c1,dp[i][j-1]+c0中的最小值

程序:

int findMinCost(string A, int n, string B, int m, int c0, int c1, int c2) {
        vector<vector<int> > dp(n+1,vector<int> (m+1,0));// write code here
        dp[0][0] = 0;
        for(int i=1;i<n+1;i++){
            dp[i][0] = i*c1;
        }
        for(int j=1;j<m+1;j++){
            dp[0][j] = j*c0;
        }
        for(int i=1;i<n+1;i++){
            for(int j=1;j<m+1;j++){
                if(A[i-1] == B[j-1]){
                    dp[i][j] = dp[i-1][j-1];
                }else{
                    int min = (dp[i-1][j]+c1) < (dp[i][j-1]+c0) ? (dp[i-1][j]+c1) : (dp[i][j-1]+c0);
                    dp[i][j] = min < (dp[i-1][j-1]+c2) ? min : (dp[i-1][j-1]+c2);
                }
            }
        }
        return dp[n][m];
    }

  (2)

     

這是一個經典的LIS(即最長上升子序列)問題,請設計一個儘量優的解法求出序列的最長上升子序列的長度。

給定一個序列A及它的長度n(長度小於等於500),請返回LIS的長度。

測試樣例:
[1,4,2,5,3],5
返回:3
程序
int getLIS(vector<int> A, int n) {
        // write code here
        vector<int> dp(n,0);
        dp[0]=1;   
        int len=1,i,j;
        for(i=1;i<n;i++){
            for(j=0;j<i;j++){
                if(A[i]>A[j])
                    dp[i]=max(dp[i],dp[j]);
            }
            dp[i]++;
            len=max(len,dp[i]);
        }
        return len;
    }

(3)

一個揹包有一定的承重cap,有N件物品,每件都有自己的價值,記錄在數組v中,也都有自己的重量,記錄在數組w中,每件物品只能選擇要裝入揹包還是不裝入揹包,要求在不超過揹包承重的前提下,選出物品的總價值最大。

給定物品的重量w價值v及物品數n和承重cap。請返回最大總價值。

測試樣例:
[1,2,3],[1,2,3],3,6
返回:6
程序:
 int maxValue(vector<int> w, vector<int> v, int n, int cap) {
        // write code here
        vector<int> dp(cap+1,0);
        for(int i=0;i<n;i++){
            for(int j=cap;j>=w[i];j--){
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
            }
        }
              
        return dp[cap];
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章