给你一个整数 n
表示数轴上的房屋数量,编号从 0
到 n - 1
。
另给你一个二维整数数组 offers
,其中 offers[i] = [starti, endi, goldi]
表示第 i
个买家想要以 goldi
枚金币的价格购买从 starti
到 endi
的所有房屋。
作为一名销售,你需要有策略地选择并销售房屋使自己的收入最大化。
返回你可以赚取的金币的最大数目。
注意 同一所房屋不能卖给不同的买家,并且允许保留一些房屋不进行出售。
示例 1:
输入:n = 5, offers = [[0,0,1],[0,2,2],[1,3,2]] 输出:3 解释: 有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 将位于 [0,0] 范围内的房屋以 1 金币的价格出售给第 1 位买家,并将位于 [1,3] 范围内的房屋以 2 金币的价格出售给第 3 位买家。 可以证明我们最多只能获得 3 枚金币。
示例 2:
输入:n = 5, offers = [[0,0,1],[0,2,10],[1,3,2]] 输出:10 解释:有 5 所房屋,编号从 0 到 4 ,共有 3 个购买要约。 将位于 [0,2] 范围内的房屋以 10 金币的价格出售给第 2 位买家。 可以证明我们最多只能获得 10 枚金币。
提示:
1 <= n <= 105
1 <= offers.length <= 105
offers[i].length == 3
0 <= starti <= endi <= n - 1
1 <= goldi <= 103
分析:首先这个题需要注意的是,end是0~n连续存在的,且同为end的售卖数组可能有多个
对于所有的offers,对于卖家售卖0~end的所有房屋最大利润为
如果end的房屋不售卖,则利润f[end+1]=f[end]
如果end的房屋售卖,则遍历所有end的售卖组合,利润f[end+1]=max(f[end+1], f[start] + gold)
class Solution {
public:
int maximizeTheProfit(int n, vector<vector<int>>& offers) {
vector<vector<std::pair<int, int>>> groups(n);
for (const auto& offer : offers) {
groups[offer[1]].emplace_back(offer[0], offer[2]);
}
vector<int> f(n + 1, 0);
for (int end = 0; end < n; end++) {
f[end + 1] = f[end];
for (const auto& group : groups[end]) {
auto start = group.first;
auto gold = group.second;
f[end + 1] = max(f[end + 1], f[start] + gold);
}
}
return f[n];
}
};