Codeforces 797 F Mice and Holes
1.5 seconds
256 megabytes
standard input
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 pj. jth 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.
The first line contains two integer numbers n, m (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.
Print one integer number — the minimum sum of distances. If there is no solution, print -1 instead.
4 5
6 2 8 9
3 6
2 1
3 6
4 7
4 7
11
7 2
10 20 30 40 50 45 35
-1000000000 10
1000000000 1
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的更多相关文章
- Mice and Holes CodeForces - 797F
Mice and Holes CodeForces - 797F 题意:有n只老鼠和m个洞,都在一个数轴上,老鼠坐标为x[1],...,x[n],洞的坐标为p[1],...,p[m],每个洞能容纳的老 ...
- AC日记——Mice and Holes codeforces 797f
797F - Mice and Holes 思路: XXYXX: 代码: #include <cmath> #include <cstdio> #include <cst ...
- Mice and Holes 单调队列优化dp
Mice and Holes 单调队列优化dp n个老鼠,m个洞,告诉你他们的一维坐标和m个洞的容量限制,问最小总距离.1 ≤ n, m ≤ 5000. 首先列出朴素的dp方程:\(f[i][j] ...
- Codeforces 959 F. Mahmoud and Ehab and yet another xor task
\(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...
- Codeforces 835 F. Roads in the Kingdom
\(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...
- codeforces 797 E. Array Queries【dp,暴力】
题目链接:codeforces 797 E. Array Queries 题意:给你一个长度为n的数组a,和q个询问,每次询问为(p,k),相应的把p转换为p+a[p]+k,直到p > n为 ...
- Codeforces 731 F. Video Cards(前缀和)
Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...
- Codeforces Beta Round #13 E. Holes 分块暴力
E. Holes Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/13/problem/E Des ...
- Codeforces 797 D. Broken BST
D. Broken BST http://codeforces.com/problemset/problem/797/D time limit per test 1 second memory lim ...
随机推荐
- 王者荣耀交流协会Beta发布文案美工展示博客
logo: 我们的logo是蓝底白字,非常简洁大气的设计感,上面印有我们的软件名称,更好的直观的彰显了我们的主题.我们的软件就是要迎合使用者,给使用者更加方便快捷的工作体验,更好的衡量自己的时间分配. ...
- "Hello World!"团队第四次会议
Scrum立会 博客内容是: 1.会议时间 2.会议成员 3.会议地点 4.会议内容 5.todo list 6.会议照片 7.燃尽图 一.会议时间: 2017年10月16日 11:44-12:18 ...
- Mac安装jee开发环境,webservice环境搭建
一.下载安装包 jdk(去官网下载) eclipse (去官网下载) tomcat(官网有9.0了)http://tomcat.apache.org/download-80.cgi#8.0.32 下载 ...
- 超级迷宫需求分析与建议-NABCD模型
超级迷宫需求分析与建议-NABCD模型 制作者-姜中希 1N-Need 需求 首先这是一个手机游戏风靡的时代,随着智能手机不断的更新问世,4G网络的不断扩大普及,越来越多的手机游戏受到广大玩家的追捧 ...
- [CF] Sasha and One More Name
题目大意 就是给一个回文串,然后进行k次分割,产生k+1个字符子串,通过重新组合这k+1个字符字串,是否会出现新的不同的回文串,且最少需要分割几段.无法产生新的回文串则输出"Impossib ...
- HDU 5861 Road 线段树区间更新单点查询
题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=5861 Road Time Limit: 12000/6000 MS (Java/Othe ...
- MySQL 查询缓存机制(MySQL数据库调优)
查询缓存机制:缓存的是查询语句的整个查询结果,是一个完整的select语句的缓存结果 哪些查询可能不会被缓存 :查询中包含UDF.存储函数.用户自定义变量.临时表.mysql库中系统表.或者包含列级别 ...
- Java实现的词频统计
要求: 1.读取文件: 2.记录出现的词汇及出现频率: 3.按照频率降序排列: 4.输出结果. 概要: 1.读取的文件路径是默认的,为了方便调试,将要统计的文章.段落复制到文本中即可:2.只支持英文: ...
- KeyBoard 操作 !
键盘操作:tab/ enter/ crtl+c ,crtl+v ; import java.awt.*; import java.awt.datatransfer.StringSelection; i ...
- (转)elasticsearch5.2.2 压测配置
1.elasticsearch.yml # ---------------------------------- Cluster ----------------------------------- ...