• [CodeForces-797F]Mice and Holes


    题目大意:
      在一条直线上,有n个老鼠,m个洞。
      每个老鼠i都有一个初始位置x[i]。
      每个洞i都有一个固定位置p[i]和容量限制c[i]。
      求所有老鼠都进洞的最小距离总和。

    思路:
      动态规划。
      用f[i][j]表示前i个洞、前j只老鼠的最小距离总和。
      用sum[i][j]表示前j个老鼠都进入第i个洞的距离总和。
      可以得到以下DP方程:
      f[i][j]=min{f[i-1][k]-sum[i][k]|k<=j}+sum[i][j]。
      然后就MLE,发现sum可以每次求出来,f如果倒着推,也可以省掉一维。
      这样空间复杂度就是O(n)的,时间复杂度是O(n^2m)的,在第42个点TLE了。
      考虑使用单调队列维护f[i-1][k]-sum[i][k]的min,做到O(nm)。

     1 #include<deque>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     register bool neg=false;
     8     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
     9     register int x=ch^'0';
    10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    11     return neg?-x:x;
    12 }
    13 const long long inf=0x7fffffffffffffffll;
    14 const int N=5001;
    15 int x[N];
    16 struct Hole {
    17     int p,c;
    18     bool operator < (const Hole &another) const {
    19         return p<another.p;
    20     }
    21 };
    22 Hole h[N];
    23 long long f[2][N],sum[N];
    24 std::deque<int> q;
    25 int main() {
    26     int n=getint(),m=getint();
    27     for(register int i=1;i<=n;i++) {
    28         x[i]=getint();
    29     }
    30     for(register int i=1;i<=m;i++) {
    31         h[i]=(Hole){getint(),getint()};
    32     }
    33     std::sort(&x[1],&x[n+1]);
    34     std::sort(&h[1],&h[m+1]);
    35     std::fill(&f[0][1],&f[0][n+1],inf);
    36     for(register int i=1;i<=m;i++) {
    37         for(register int j=1;j<=n;j++) { 
    38             sum[j]=sum[j-1]+std::abs(h[i].p-x[j]); 
    39         }
    40         q.clear();
    41         q.push_back(0);
    42         for(register int j=1;j<=n;j++) {
    43             while(!q.empty()&&j-q.front()>h[i].c) {
    44                 q.pop_front();
    45             }
    46             while(!q.empty()&&f[!(i&1)][j]-sum[j]<=f[!(i&1)][q.back()]-sum[q.back()]) {
    47                 q.pop_back();
    48             }
    49             q.push_back(j);
    50             f[i&1][j]=f[!(i&1)][q.front()]+sum[j]-sum[q.front()];
    51         }
    52     }
    53     printf("%I64d
    ",f[m&1][n]!=inf?f[m&1][n]:-1);
    54     return 0;
    55 }
  • 相关阅读:
    CobaltStrike上线Linux主机(CrossC2)
    Active-Directory活动目录备忘录
    CVE-2020-5902 F5 BIG-IP 远程代码执行漏洞复现
    SSTI-服务端模板注入漏洞
    powershell代码混淆绕过
    绕过PowerShell执行策略方法
    "dpkg: 处理归档 /var/cache/apt/archives/libjs-jquery_3.5.1+dfsg-4_all.deb (--unpack)时出错"的解决方法
    firda安装和使用
    内网渗透-跨域攻击
    Web-Security-Learning
  • 原文地址:https://www.cnblogs.com/skylee03/p/7675917.html
Copyright © 2020-2023  润新知