题意:
给你一个 events 数组,其中 events[i] = [startDayi, endDayi, valuei] ,
表示第 i 个会议在 startDayi 天开始,第 endDayi 天结束,
如果你参加这个会议,你能得到价值 valuei 。
同时给你一个整数 k 表示你能参加的最多会议数目。
你同一时间只能参加一个会议。
如果你选择参加某个会议,那么你必须 完整 地参加完这个会议。
会议结束日期是包含在会议内的,
也就是说你不能同时参加一个开始日期与另一个结束日期相同的两个会议。
请你返回能得到的会议价值 最大和 。
数据范围:
1 <= k <= events.length
1 <= k * events.length <= 1e6
1 <= startDayi <= endDayi <= 1e9
1 <= valuei <= 1e6
解法:
令d[i][j]表示前i天,使用了j次机会能获得的最大值,
由于i这一维很大,达到了1e9,但是events.length很小,因此需要先离散化一下(l,r,v)中的(l,r).
如果选择(i+1,r,v),那么d[i][j]可以转移到d[r][j+1],转移收益为v,
如果不选,那么d[i][j]可以转移到d[i+1][j].
dp一下就行了,有点01背包的意思.
code:
class Solution {
public:
int maxValue(vector<vector<int>>& e, int k) {
vector<int>temp;
for(auto i:e){
temp.push_back(i[0]);
temp.push_back(i[1]);
}
sort(temp.begin(),temp.end());
temp.resize(unique(temp.begin(),temp.end())-temp.begin());
for(auto&i:e){
i[0]=lower_bound(temp.begin(),temp.end(),i[0])-temp.begin()+1;
i[1]=lower_bound(temp.begin(),temp.end(),i[1])-temp.begin()+1;
}
vector<pair<int,int> >g[temp.size()+5];
for(auto i:e){
g[i[0]].push_back({i[1],i[2]});
}
vector<vector<int>>d(temp.size()+5,vector<int>(k+5,0));
for(int i=0;i<=temp.size();i++){
for(int j=0;j<=k;j++){
d[i+1][j]=max(d[i+1][j],d[i][j]);
if(j!=k){
for(auto p:g[i+1]){
int r=p.first,v=p.second;
d[r][j+1]=max(d[r][j+1],d[i][j]+v);
}
}
}
}
int ans=0;
for(int i=0;i<=temp.size();i++){
for(int j=0;j<=k;j++){
ans=max(ans,d[i][j]);
}
}
return ans;
}
};