D. Searchlights 枚举+思维
题目大意:
给你n个机器人和m个监控器,你每次可以指挥所有的机器人x+1或者y+1,要求是最后对于每一个机器人,必须满足 ax>cy and bx>dy,也就是对于每一个机器人,他都要在任意一个监控器的右上方。
题解:
- 先求出每一个机器人横坐标走出去的dx所需要的最大的dy,用need数组记录
- 这个need数组记录的是对于任意的一个机器人,如果存在一个监控器可以监控到他,那么一定会算一次need
- 从大到小遍历,那么如果 i<j, 此时对于 j 想要从纵坐标走出去的need 应该是now = max(now,need[j]),遍历到 j now = max(now,need[j])
- 如果 need[x] 为真,need[x-1] =0 ,那么说明往右走x和往右走x-1是一样的,在 x 更新now之后,在 x-1 就不需要重新更新now
- 其实这样子写,有点像线段树的区间覆盖,对于索引x 应该更新所有y(y<x)的need,取最大值,最后就得出往右走x步所需要的最小的往上走的距离使得所有的机器人都不受监控。
#include <bits/stdc++.h>
using namespace std;
const int maxn =2200;
int need[1000010],a[maxn],b[maxn],c[maxn],d[maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
for(int i=1;i<=m;i++) scanf("%d%d",&c[i],&d[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i]<=c[j]&&b[i]<=d[j]){
need[c[j]-a[i]] = max(need[c[j]-a[i]],d[j]-b[i]+1);
}
}
}
int ans = 1e9,realneed = 0;
for(int i=1e6;i>=0;i--){
realneed = max(realneed,need[i]);
ans = min(ans,realneed+i);
}
printf("%d
", ans);
return 0;
}