D. Searchlights 枚举+思维

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\n", ans);
    return 0;
}
posted @ 2020-10-09 11:39  EchoZQN  阅读(78)  评论(0编辑  收藏  举报