• [CF1253E] Antenna Coverage


    [CF1253E] Antenna Coverage - dp

    Description

    街道上有 (n le 80) 个天线。第 (i) 个天线的位置为 (x_i),以及一个范围值 (s_i);第 (i) 个天线的覆盖范围是 ([x_i-s_i,x_i+s_i])。每次操作,你可以花费 (1) 代价,使得第 (i) 个天线的 (s_i) 增加一。每个天线都可以进行多次操作。现在请问你最少需要花费多少代价,使 ([1,m] (m le 10^5)) 编号内的每一个位置都被至少一个天线覆盖。

    Solution

    (f[i]) 表示 ([1,i]) 被全部覆盖的最小花费,初态 (f[i]=i)

    如果 i 已经被某个初始区间完全覆盖了,那么可以从 (f[i-1]) 转移过来

    另一种转移是,有一个区间要扩张,枚举每个区间,这里我们只取左边的区间向右扩张

    如果区间的右端点在 i 左边,那么可以考虑这个区间扩张后恰好覆盖到 i 的左端点的情况,也就是从 (f_{l_j-i+r_j)+i-r_j) 转移过来

    为什么不同时取右边的区间向左扩张?假设方案中右边有个区间在后面扩张了,那么转移的时候取的转移来源会更偏左……,因此,对于同一个点而言,转移到它的所有状态中,转移点靠右的状态一定不会更劣

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 100005;
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int n, m;
        cin >> n >> m;
    
        vector<int> x(n + 2), s(n + 2), l(n + 2), r(n + 2), f(m + 2);
        for (int i = 1; i <= m; i++)
            f[i] = i;
        for (int i = 1; i <= n; i++)
        {
            cin >> x[i] >> s[i];
            l[i] = x[i] - s[i];
            r[i] = x[i] + s[i];
        }
        for (int i = 1; i <= m; i++)
        {
            int flag = 0;
            for (int j = 1; j <= n; j++)
                if (l[j] <= i && r[j] >= i)
                    flag = 1;
            if (flag)
            {
                f[i] = f[i - 1];
            }
    
            for (int j = 1; j <= n; j++)
            {
                if (r[j] < i)
                {
                    f[i] = min(f[i], f[max(0ll, l[j] - i + r[j] - 1)] + i - r[j]);
                }
            }
        }
        cout << f[m] << endl;
    }
    
  • 相关阅读:
    传感器仿真平台——数据生成模块(三)
    写一个ES6 的遍历目录函数
    编码风格
    关于DOM事件的一个例子
    WEB DB
    表格资料
    css3 鼠标移入移出效果
    css 3D
    正向代理和反向代理
    FileReader 对象
  • 原文地址:https://www.cnblogs.com/mollnn/p/14390176.html
Copyright © 2020-2023  润新知