E 多米诺骨牌
,贪心的将区间
按左端点排序,再按右端点排序。最后就是直接将区间合并,枚举每一个区间,当之前枚举的连续区间的右端点
当前枚举区间的左端点则区间可以合并,否则断开,重新开一个区间。详细代码如下:
void solve()
{
int n,m;
cin >> n >> m;
vector<int> x(n+1),h(n+1) ;
for(int i = 1;i <= n;i ++) cin >> h[i] ;
for(int i = 1;i <= n;i ++) cin >> x[i] ;
vector<pair<int,int>> edge;
for(int i = 1;i <= n;i ++)
{
edge.push_back({x[i] , x[i] + h[i]}) ;
}
sort(edge.begin(),edge.end()) ;
vector<pair<int,int>> Edge;
vector<int> w ;
int st = -2e9 , ed = -2e9 , c = 0;
for(int i = 0 ;i < edge.size() ;i ++)
{
if(ed >= edge[i].x || st == -2e9)
{
ed = max(ed , edge[i].y) ;
if(st == -2e9) st = edge[i].x ;
c ++ ;
}else
{
Edge.push_back({st,ed}) ;
w.push_back(c) ;
c = 1 ;
st = edge[i].x , ed = edge[i].y ;
}
}
if(st != -2e9)
{
Edge.push_back({st,ed}) ;
w.push_back(c) ;
}
sort(w.begin(),w.end(),greater<int>()) ;
int ans = 0 ;
for(int i = 0 ;i < min(m , (int)w.size()) ; i ++)
{
ans += w[i] ;
}
cout << ans << '\n' ;
}