動態規劃——陣列單調和
阿新 • • 發佈:2018-12-06
題目:
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; } };