https://codeforces.com/contest/1408/problem/D
思路:
有很多人和很多监控,考虑枚举。
考虑将横纵坐标分开考虑。
先在有效工作的监控中枚举。
考虑对于每个横坐标差为x的监控来说,对应的和监控横坐标差为x的人至少需要向上走y步才能逃离。
然后再来枚举向右走的步数从最大的1e6到0中,能走出来的的向上走+向右走的最小值是多少。
什么意思呢?
就是从向右走的步数从大到小的枚举中,比如枚举向右走了x步,那么必然保证向右走<x步就能逃离的人必然能逃离。然后剩下的不能通过向右走逃离的在枚举的过程中更新向上走的最大值,那些人通过向上走来逃离。
因而相当于枚举了往上走的步数和往右走的步数必然能逃离的所有情况。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e3+100;
typedef int LL;
struct rob{
LL x,y;
}re[maxn];
struct light{
LL x,y;
}li[maxn];
LL v[1000060];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n,m;cin>>n>>m;
for(LL i=1;i<=n;i++){
cin>>re[i].x>>re[i].y;
}
for(LL j=1;j<=m;j++){
cin>>li[j].x>>li[j].y;
}
for(LL i=1;i<=n;i++){
for(LL j=1;j<=m;j++){
if(li[j].x-re[i].x>=0&&li[j].y-re[i].y>=0){
v[li[j].x-re[i].x]=max(v[li[j].x-re[i].x],(li[j].y-re[i].y+1));
//对于每个横坐标差为x的监控来说,至少需要向上走y步才能出去
}
}
}
LL ans=1e7;LL r=-1e7;
for(int i=1000000;i>=0;i--){ //注意从大到小,不然会出现不存在的情况当最小值
r=max(r,v[i]);///往右走i步时,至少向上需要多少步
ans=min(ans,r+i); //加上往右走的步数,枚举总体最小步数
}
cout<<ans<<endl;
return 0;
}