zoukankan      html  css  js  c++  java
  • Codeforces Round #600 (Div. 2) E. Antenna Coverage (DP)

    传送门

    思路见注释;

    AC代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    const int N=2e5+5;
    const double inf=0x3f3f3f3f;
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define mk make_pair
    #define pb push_back
    #define mem(a,b) memset(a,b,sizeof(a))
    #define debug puts("...")
    LL read()
    {
        LL x=0,t=1;
        char ch=getchar();
        while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    //f[i] 为 [1,i] 被覆盖的最小花费
    int f[N],x[N],s[N];
    int main()
    {
        int n=read(),m=read();
        for(int i=0;i<=m;i++) f[i]=m;//把[1,i]看作[1,m]的子问题,覆盖[1,m] 最多花费 m,那么其子问题 覆盖[1,i] 最多需要 i;
        for(int i=1;i<=n;i++)
        {
            x[i]=read();
            s[i]=read();
        }
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++)
                if(x[j]<=i) f[i]=min(f[i],f[max(x[j]*2-i-1,0)]+max(i-x[j]-s[j],0));//第一种情况,让 x[j] 向后扩张覆盖 i 则需要至少 i-x[j]-s[j]的花费(扩张的花费,其可能为负,可能已经被覆盖了),x[j]是向两边同时扩张的,所以 算出 i关于 x[j] 对称的点的前一个位置
                else f[i]=min(f[i],f[max(x[j]-s[j]-1,0)] );//第二种情况,是否可能被后面的点直接覆盖掉(不扩张),在这里不考虑 后面的点扩张之后把前面的i覆盖的情况,因为 x[j] 向前扩张至i,同时也会向后扩张至 i 关于 x[j] 的对称点k, 对于k而言 的第一种种情况与 i的第二种情况等价(都是覆盖后,通过 f[i-1] 转移),所以没有必要,而且也避免了后效性。
        }
        printf("%d
    ",f[m]);
        return 0;
    }
     
    
  • 相关阅读:
    MFC绘制直角坐标系
    mfc画波形函数
    ciscn_2019_ne_5
    ciscn_2019_n_5
    [ZJCTF 2019]NiZhuanSiWei
    ciscn_2019_n_1
    pwn-100
    2014提高组笔试错题
    BZOJ3211: 花神游历各国
    主席树模板
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025177.html
Copyright © 2011-2022 走看看