Russian Doll Envelopes - LeetCode
题目:
You have a number of envelopes with widths and heights given as a pair of integers (w, h). One envelope can fit into another if and only if both the width and height of one envelope is greater than the width and height of the other envelope.Example:
Given envelopes = [[5,4],[6,4],[6,7],[2,3]], the maximum number of envelopes you can Russian doll is 3 ([2,3] => [5,4] => [6,7]).
补一下上周的作业。
又又挑了一道动态规划题目(有点虚期末出这类题)
给出一组信封的长宽,要求出最大嵌套信封数量
看完题目就有一个很自然的想法,要嵌套当然是先选一个最小的,然后从小到大依次尝试,这样就要按照大小对信封排序,信封的大小有两个属性,长和宽,所以排序要使用基数排序。
两个属性值的基数排序用pair比较方便(碰巧题目给出的数据也是这个形式),具体方式在下面的代码里
然后就是重点环节,
使用一个二维数组dp[n][2]
,dp[i][0]
表示不用第i个信封,前i个信封的最大嵌套数量;dp[i][1]
表示使用第i个信封,前i个信封的最大嵌套数量
dp[i][0] = max(dp[i-1][0],dp[i-1][1])
这是显然的
dp[i][1]
就需要去遍历前i-1个信封,看是否能够套住
class Solution {
public:
int maxEnvelopes(vector< pair<int, int> >& envelopes) {
if (envelopes.size() == 0) return 0;
sort(envelopes.begin(), envelopes.end());
vector< vector<int> > dp(envelopes.size()+1, vector<int>(2, 0));
dp[0][0] = 0;
dp[0][1] = 1;
for (int i = 1; i < envelopes.size(); i++) {
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
dp[i][1] = 1;
for (int j = 0; j < i; j++) {
if (envelopes[i].first > envelopes[j].first && envelopes[i].second > envelopes[j].second) {
dp[i][1] = max(dp[i][1], dp[j][1]+1);
//这里只需要比较dp[i][1]而不需要比较dp[i][0],因为dp[i][0]的值一定等于某个dp[k][1],k<i
}
}
}
return max(dp[envelopes.size()-1][0],dp[envelopes.size()-1][1]);
}
};