动态规划——数组单调和

题目:

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;
	}
};

猜你喜欢

转载自blog.csdn.net/lxin_liu/article/details/80256126