1. 程式人生 > >演算法分析與設計期中測試——最小和

演算法分析與設計期中測試——最小和

從數列A[0], A[1], A[2], …, A[N-1]中選若干個數,要求對於每個i(0<=i< N-1),A[i]和A[i+1]至少選一個數,求能選出的最小和.

1 <= N <= 100000, 1 <= A[i] <= 1000

請為下面的Solution類實現解決上述問題的函式minSum,函式引數A是給出的數列,返回值為所求的最小和.

class Solution {
public:
int minSum(vector& A) {

}

};

例1:A = {2, 5, 2},答案為4.

例2:A = {2, 5, 4},答案為5.

注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.

比較容易往動態規劃的方向想,一開始用遞迴的方法做結果超時了,改成迴圈就可以了。不得不說動態規劃方法真的簡潔優雅效率又高,就是要考慮清楚邏輯的完備性。狀態轉移方程如下,意思就是前i個數字的最小和有兩種情況,一種包括第i個數字再加上前i-1個數字的最小和,另外一種包括第i-1個數字再加上前i-2個數字的最小和。要注意的是,比如說取了第i個數字不代表就不會取第i-1個數字,如2,5,2,1最優的情況是取2,2,1。

dp[i] = min(dp[i - 1
] + A[i], dp[i - 2]+A[i-1]);
class Solution {
public:
    int minSum(vector<int>& A) {
        int *dp = new int[A.size()];

        if (A.size() == 1) {
            return A[0];
        }
        if (A.size() == 2) {
            return min(A[0], A[1]);
        }
        if (A.size() == 3) {
            min(A
[0] + A[2], A[1])
; } dp[0] = A[0]; dp[1] = min(A[0], A[1]); dp[2] = min(A[0] + A[2], A[1]); for (int i = 3; i < A.size(); i++) { dp[i] = min(dp[i - 1] + A[i], dp[i - 2]+A[i-1]); } return dp[A.size() - 1]; } };