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' ;
}