DP intro: Rod cutting problem

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011934885/article/details/85234462

Given a rod of length n inches and an array of prices that contains prices of all pieces of size smaller than n. Determine the maximum value obtainable by cutting up the rod and selling the pieces. For example, if length of the rod is 8 and the values of different pieces are given as following, then the maximum obtainable value is 22 (by cutting in two pieces of lengths 2 and 6)

length   | 1   2   3   4   5   6   7   8  
--------------------------------------------
price    | 1   5   8   9  10  17  17  20

这是算法导论的DP入门题,重新整理一下引入的思路。
基本的recusive写法:

int cut_rod (vector<int>& p, int n) {
	if (n == 0) return 0;
	int q = INT_MIN;
	for (int i = 1; i <= n; i++) {
		q = max(q, p[i] + cut_rod(p. n - i));
	}
	return q;
}

这个例子就很好的体现了引入DP的意义,当我们普通的divide and conquer或者recursion出现大量的重复子问题的时候,对这些计算过的子问题进行存储就很有必要。

int Memoized_cut_rod (vector<int>& p, int n) {
	vector<int> r(n, INT_MIN); // recording
	r[0] = 0;
	return Memoized_cut_rod_helper(p, n, r);
}
int Memoized_cut_rod_helper (vector<int>& p, int n, vector<int>& r) {
	if (r[n] >= 0) return r[n];
	int q = INT_MIN;
	for (int i = 1; i <= n; i++) {
		q = max(q, p[i] + Memoized_cut_rod_helper(p, n - i, r));
	}
	r[n] = q;
	return r[n];
}

也可以换种写法:

int bottom_up_cut_rod (vector<int>& p, int n) {
	vector<int> r(n, INT_MIN);
	r[0] = 0;
	for (int j = 1; j <= n; j++) {
		int q = INT_MIN;
		for (int i = 1; i <= j; i++) {
			q = max(q, p[i] + r[j - i]);
		}
		r[j] = q;
	}
	return r[n]; 
}

extended: how to reconstruct the solution for the maximum revenue.

int Extended_bottom_up_cut_rod (vector<int>& p, int n, vector<int>& s) {
	vector<int>& r(n, INT_MIN);
	r[0] = 0;
	for (int j = 1; j <= n; j++) {
		int q = INT_MIN;
		for (int i = 1; i <= j; i++) {
			if (q < p[i] + r[j - i]) {
				r[j] = q;
				s[j] = i;
			}
		}
	}
	return r[n];
}

猜你喜欢

转载自blog.csdn.net/u011934885/article/details/85234462
今日推荐