1. 程式人生 > >動態規劃——陣列單調和

動態規劃——陣列單調和

題目:

https://www.nowcoder.com/practice/8397609ba7054da382c4599d42e494f3?tpId=49&&tqId=29364&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking

現定義陣列單調和為所有元素i的f(i)值之和。這裡的f(i)函式定義為元素i左邊(不包括其自身)小於等於它的數字之和。請設計一個高效演算法,計算陣列的單調和。

給定一個數組A同時給定陣列的大小n,請返回陣列的單調和。保證陣列大小小於等於500,同時保證單調和不會超過int範圍。

測試樣例:
[1,3,5,2,4,6],6
返回:27

程式碼:

class MonoSum {
public:
    //解法二:歸併排序
     int count = 0;
	void Merge(vector<int> &A, int begin, int end, int middle) {
		if (begin >= end)
			return;
		int left_index = begin, right_index = middle + 1;
		vector<int> tem;
		while (left_index <= middle && right_index <= end) {
			if (A[left_index] <= A[right_index]) {
				count += (end - right_index + 1)*A[left_index];
				tem.push_back(A[left_index]);
				left_index++;
			}
			else {
				tem.push_back(A[right_index]);
				right_index++;
			}
		}
		for (int i = left_index; i <= middle; i++)
			tem.push_back(A[i]);
		for (int i = right_index; i <= end; i++)
			tem.push_back(A[i]);
		for (int i = begin; i <= end; i++)
			A[i] = tem[i-begin];
	}
	void mergeSort(vector<int> &A, int begin, int end) {
		int middle = (begin + end) / 2;
		if (begin < middle)
			mergeSort(A, begin, middle);
		if (end > middle + 1)
			mergeSort(A, middle + 1, end);
		Merge(A, begin, end, middle);
	}
	int calcMonoSum(vector<int> A, int n) {
		if (n < 2) 
			return 0;
		mergeSort(A, 0, n - 1);
		cout << count << endl;
		system("pause");
		return count;
	}
    //解法一
    /*
    int calcMonoSum(vector<int> A, int n) {
        if (n == 1)
            return A[0];
        int result = 0;
        for(int i=0; i<n; i++)
            result += count_num(A, n, i) * A[i];
        return result;
    }
    int count_num(vector<int> &A, int n, int i){
        int count= 0;
        for(int j = i+1; j<n; j++)
            if(A[j] >= A[i])
                count++;
        return count;
    }
    */
};

解法三:動態規劃

class MonoSum {
public:
	int calcMonoSum(vector<int> A, int n) {
		int *dp = new int[n];
		for (int i = 0; i<n; i++)
			dp[i] = 0;
		for (int i = 1; i<n; i++) {
			for (int j = 0; j<i; j++) {
				if (A[j] <= A[i]) {
					if (dp[i] <= dp[j] + A[j])
						dp[i] = dp[j] + A[j];
					else
						dp[i] = dp[i] + A[j];
				}
			}
		}
		int res = 0;
		for (int i = 0; i<n; i++)
			res = res + dp[i];
		cout << res << endl;
		return res;
	}
};