首先注意到先输入高度再输入位置,我们先开一个结构体

1,输入数组,之后注意到位置并非按顺序来,所以我们进行结构体排序

2,我们设置一个变量k,表示当前多米诺骨牌倒下后最大的覆盖范围(int k =0)之后遍历数组以k=max(k,arr[i].wei+arr[i].gao)更新k的值,这时我们需要一个cnt数组表示当前连续段的长度

2的代码实现:

int j=0;

int k=0;//覆盖范围

sum[0]=1;

for(int i=0;i<n-1;i++){

k=max(k,arr[i].w+arr[i].h);

if(k>=arr[i+1].w){

sum[j]++;

}else{

j++;

sum[j]=1;

}

}

3.最后就是贪心策略,写一个cmp将数组从大到小排序即可

完整代码如下

#include <bits/stdc++.h>

#define endl '\n'

using namespace std;

struct pp{

int w,h;

}arr[200005];

int cmp(pp x,pp y){

return x.w<y.w;

}

int cmp1(int x,int y){

return x>y;

}

int sum[200005];

int main(){

cin.tie(0)->sync_with_stdio(0);

int t;cin>>t;

while(t--){

int n,m;

cin>>n>>m;

for(int i=0;i<n;i++){

cin>>arr[i].h;

}

for(int i=0;i<n;i++){

cin>>arr[i].w;

}

sort(arr,arr+n,cmp);

int j=0;

int k=0;//覆盖范围

sum[0]=1;

for(int i=0;i<n-1;i++){

k=max(k,arr[i].w+arr[i].h);

if(k>=arr[i+1].w){

sum[j]++;

}else{

j++;

sum[j]=1;

}

}

int ans=0;

if(m>j){

cout<<n<<endl;

continue;

}

sort(sum,sum+j,cmp1);

for(int i=0;i<m;i++){

ans+=sum[i];

}

cout<<ans<<endl;

}

}