[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 }
原文地址:https://www.cnblogs.com/skylee03/p/7675917.html