[Grakn Forces 2020]-D. Searchlights (暴力+DP)

[Grakn Forces 2020]-D. Searchlights (暴力+DP)

题面:

思路:

设数组\(c_i\) 代表将所有机器人右移\(\mathit i\) 步后,将所有机器人移除探照灯的监视范围至少多少步上移。

那么如何获得数组\(\mathit c\)呢?

我们\(O(n*m)\)枚举每一对机器人\(\mathit i\)和探测灯\(\mathit j\),如果\(a_i.x\leq b_j.x\)

我们更新\(c[b_j.x-a_i.x]=max(c[b_j.x-a_i.x],b[j].y-a[i].y+1)\)

最后再对数组\(\mathit c\)做一个后缀最大值,然后答案就是

\[max_{i=0}^{i=1e6+1}{c_i+i} \]

代码:

int n, m;
pii a[2020];
pii b[2020];
int c[maxn];
int main()
{
#if DEBUG_Switch
    freopen("C:\\code\\input.txt", "r", stdin);
#endif
    //freopen("C:\\code\\output.txt","w",stdout);
    n = readint();
    m = readint();
    repd(i, 1, n)
    {
        a[i].fi = readint();
        a[i].se = readint();
    }
    repd(i, 1, m)
    {
        b[i].fi = readint();
        b[i].se = readint();
    }
    repd(i, 1, n)
    {
        repd(j, 1, m)
        {
            if (b[j].fi >= a[i].fi)
            {
                // cout << b[j].fi - a[i].fi << " " << b[j].se - a[i].se + 1 << endl;
                c[b[j].fi - a[i].fi] = max(c[b[j].fi - a[i].fi], b[j].se - a[i].se + 1);
            }
        }
    }
    int ans = inf;
    for (int i = 1000001; i >= 0; --i)
    {
        c[i] = max(c[i], c[i + 1]);
        ans = min(ans, c[i] + i);
    }
    printf("%d\n", ans);
    return 0;
}
 
posted @ 2020-10-03 15:04  茄子Min  阅读(181)  评论(0编辑  收藏  举报