F. Mice and Holes
time limit per test            

1.5 seconds

memory limit per test      

256 megabytes

input

standard input

output

standard output

One day Masha came home and noticed n mice in the corridor of her flat. Of course, she shouted loudly, so scared mice started to run to the holes in the corridor.

The corridor can be represeted as a numeric axis with n mice and m holes on it. ith mouse is at the coordinate xi, and jth hole — at coordinate pjjth hole has enough room for cj mice, so not more than cj mice can enter this hole.

What is the minimum sum of distances that mice have to go through so that they all can hide in the holes? If ith mouse goes to the hole j, then its distance is |xi - pj|.

Print the minimum sum of distances.

Input

The first line contains two integer numbers nm (1 ≤ n, m ≤ 5000) — the number of mice and the number of holes, respectively.

The second line contains n integers x1, x2, ..., xn ( - 109 ≤ xi ≤ 109), where xi is the coordinate of ith mouse.

Next m lines contain pairs of integer numbers pj, cj ( - 109 ≤ pj ≤ 109, 1 ≤ cj ≤ 5000), where pj is the coordinate of jth hole, and cj is the maximum number of mice that can hide in the hole j.

Output

Print one integer number — the minimum sum of distances. If there is no solution, print -1 instead.

Examples
input
4 5
6 2 8 9
3 6
2 1
3 6
4 7
4 7
output
11
input
7 2
10 20 30 40 50 45 35
-1000000000 10
1000000000 1
output
7000000130

题意:n个老鼠m个洞在数轴上,给出老鼠坐标,再给出每个洞的坐标和最多容纳的老鼠数量,问所有的老鼠到洞里所需要的最短距离,不能则输出-1

分析题目可得,最优方案一定是 某一个洞里容纳了坐标临近的老鼠

即将洞按坐标排序,老鼠按坐标排序,第i个洞容纳的是第k——s只老鼠,第i+1个洞容纳的是第s+1——t只老鼠

令f[j][i]表示前j个洞,容纳了前i只老鼠的最短距离

s[j][i]表示第1——i只老鼠全到第j个洞的距离和,即前缀和

那么f[j][i]可以由f[j-1][i-1],f[j-1][i-2]……f[j-1][i-容量]转移过来

动态转移方程:f[j][i]=min(f[j-1][k]+s[j][i]-s[j][k])

事件复杂度:n²

可以用单调队列优化

对于每一个j和i,s[j][i]是定值,f[j][i]=min(f[j-1][k]-s[j][k])+s[j][i]

对于每一个j,维护一个f[j-1][k]-s[j][k]的单调递增队列

f[j][i]就等于  队首+s[j][i]

然后滚动数组滚起来~~

(虽然不用滚动数组也能A)

不用滚动数组版:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
int mouse[],que[];
ll sum,f[][],s[];
struct HOLE
{
int pos,capa;
}hole[];
bool cmp(HOLE p,HOLE k) { return p.pos<k.pos; }
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&mouse[i]);
for(int i=;i<=m;i++) scanf("%d%d",&hole[i].pos,&hole[i].capa),sum+=hole[i].capa;
if(n>sum) { printf("-1"); return ; }
sort(mouse+,mouse+n+);
sort(hole+,hole+m+,cmp);
memset(f,,sizeof(f));
f[][]=;
for(int j=;j<=m;j++)
{
int head=,tail=;
que[]=;
for(int i=;i<=n;i++) s[i]=s[i-]+abs(mouse[i]-hole[j].pos);
for(int i=;i<=n;i++)
{
while(head<tail&&que[head]<i-hole[j].capa) head++;
while(head<tail&&f[j-][i]-s[i]<=f[j-][que[tail-]]-s[que[tail-]]) tail--;
que[tail++]=i;
f[j][i]=f[j-][que[head]]+s[i]-s[que[head]];
}
}
printf("%lld",f[m][n]);
}
滚动数组:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
int mouse[],que[];
ll sum,f[][],s[];
struct HOLE
{
int pos,capa;
}hole[];
bool cmp(HOLE p,HOLE k) { return p.pos<k.pos; }
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&mouse[i]);
for(int i=;i<=m;i++) scanf("%d%d",&hole[i].pos,&hole[i].capa),sum+=hole[i].capa;
if(n>sum) { printf("-1"); return ; }
sort(mouse+,mouse+n+);
sort(hole+,hole+m+,cmp);
memset(f,,sizeof(f));
f[][]=;
int j,now=,pre=;
for(j=;j<=m;j++,swap(now,pre))
{
int head=,tail=;
que[]=;
for(int i=;i<=n;i++) s[i]=s[i-]+abs(mouse[i]-hole[j].pos);
for(int i=;i<=n;i++)
{
while(head<tail&&que[head]<i-hole[j].capa) head++;
while(head<tail&&f[pre][i]-s[i]<=f[pre][que[tail-]]-s[que[tail-]]) tail--;
que[tail++]=i;
f[now][i]=f[pre][que[head]]+s[i]-s[que[head]];
}
}
printf("%lld",f[pre][n]);
}

while(head<tail&&que[head]<i-hole[j].capa) 不能加等号,因为这一次的范围是以i-hole[j].capa开始
while(head<tail&&f[pre][i]-s[i]<=f[pre][que[tail-1]]-s[que[tail-1]])  要加等号,可以更新队列中的老鼠的标号,使其更大,更有利于后面的转移
 
刚开始想的是三维dp,f[j][i][k] 其中k表示最后一个洞容纳了几只老鼠,这一维是冗余的,且难以设计方程
这一维起的作用是转移状态的上界,完全可以在枚举i时只枚举合法的

Codeforces 797 F Mice and Holes的更多相关文章

  1. Mice and Holes CodeForces - 797F

    Mice and Holes CodeForces - 797F 题意:有n只老鼠和m个洞,都在一个数轴上,老鼠坐标为x[1],...,x[n],洞的坐标为p[1],...,p[m],每个洞能容纳的老 ...

  2. AC日记——Mice and Holes codeforces 797f

    797F - Mice and Holes 思路: XXYXX: 代码: #include <cmath> #include <cstdio> #include <cst ...

  3. Mice and Holes 单调队列优化dp

    Mice and Holes 单调队列优化dp n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离.1 ≤ n, m ≤ 5000. ​ 首先列出朴素的dp方程:\(f[i][j] ...

  4. Codeforces 959 F. Mahmoud and Ehab and yet another xor task

    \(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...

  5. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  6. codeforces 797 E. Array Queries【dp,暴力】

    题目链接:codeforces 797 E. Array Queries   题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...

  7. Codeforces 731 F. Video Cards(前缀和)

    Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...

  8. Codeforces Beta Round #13 E. Holes 分块暴力

    E. Holes Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/13/problem/E Des ...

  9. Codeforces 797 D. Broken BST

    D. Broken BST http://codeforces.com/problemset/problem/797/D time limit per test 1 second memory lim ...

随机推荐

  1. 王者荣耀交流协会-Alpha发布用户使用报告

    用户数量:10人 姓名如下(包括化名):张小斌.王瑞瑞.蛋蛋.小美.晨曦.小丽.张利刚.小闫.小谢.小崔 寻找的用户多为王者荣耀交流协会成员的同学,对管理时间有着强烈的需求,也对PSP Daily软件 ...

  2. 王者荣耀交流协会--第3次Scrum会议

    Scrum master:王玉玲 要求1:工作照片 要求2:时间跨度:2017年10月15号  6:00--6:24  共计24min要求3:地点:传媒西楼204,会议室要求4:立会内容:1.从昨日会 ...

  3. web表格代码(5)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. 1029 C语言文法翻译(2)

    program à external_declaration | program external_declaration 翻译:<源程序>→ <外部声明> | <源程序 ...

  5. <问吧>调查问卷心得体会

    <问吧>调查问卷心得与体会 在这之前,我们已经组成了一个六个人的小团队---“走廊奔跑队”,我们这次做的这个项目的名称是:问吧.在项目实施之前,我们必做的一步就是需求分析,目的就是充分了解 ...

  6. [CB] 中国超算前100 (联想40 曙光40 浪潮12 国防科大4 华为2 国家并行工程中心2 )

    转帖 地址: https://www.cnbeta.com/articles/tech/779633.htm 榜单的前三名和去年相比没有任何变化,依然分别是部署在国家超级计算无锡中心的“神威·太湖之光 ...

  7. 数据输出保存生成word文档

    ob_start(); //打开缓冲区 $header_str = '<html xmlns:o="urn:schemas-microsoft-com:office:office&qu ...

  8. python之enumerate()学习

    X = 'abcdefghijklmn' for (index,char) in enumerate(X): print (index, char) 利用enumerate()函数,可以在每次循环中同 ...

  9. 【Python】Python流程控制

    1)if条件测试 Python的比较操作 所有的Python对象都支持比较操作 测试操作符('=='操作符测试值的相等性: 'is'表达式测试对象的一致性) Python中不同类型的比较方法 数字:通 ...

  10. C++解析(21):四个操作符

    0.目录 1.逻辑操作符的陷阱 2.逗号操作符的分析 3.前置操作符和后置操作符 4.小结 1.逻辑操作符的陷阱 逻辑运算符的原生语义: 操作数只有两种值(true和false) 逻辑表达式不用完全计 ...