汕头市队赛 SRM16 T2
描述
猫和老鼠,看过吧?猫来了,老鼠要躲进洞里。在一条数轴上,一共有n个洞,位置分别在xi,能容纳vi只老鼠。一共有m只老鼠位置分别在Xi,要躲进洞里,问所有老鼠跑进洞里的距离总和最小是多少。
输入格式
两个用空格隔开的整数m和n。
这一行m个数字分别表示老鼠的位置
接下来n行每行两个数字分别表示洞的位置和容纳量
输出格式
一个整数,表示最小的距离总和。(如果无解,输出-1)
样例输入
4 5
6 2 8 9
3 6
2 1
3 6
4 7
4 7
样例输出
11
——————————————————————————
n <= 500, m <= 500 的时候可以写费用流 但是要比较好的建图方式
nm的建图肯定要挂
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=2e3+,inf=0x3f3f3f3f;
const LL mx=1e15;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>'') {if(c=='-') f=-; c=getchar();}
while(c>=''&&c<='') {ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,q[M],vis[M];
int N,S,T;
LL ans,d[M];
struct node{int to,next,flow;LL cost;}e[M*M];
int first[M],cnt=,cur[M];
void ins(int a,int b,int flow,LL cost){e[++cnt]=(node){b,first[a],flow,cost}; first[a]=cnt;}
void insert(int a,int b,int flow,LL cost){ins(a,b,flow,cost); ins(b,a,,-cost);}
bool spfa(){
for(int i=S;i<=T;i++) d[i]=mx;
int head=,tail=;
q[]=T; vis[T]=; d[T]=;
while(head!=tail){
int x=q[head++]; if(head>M) head=;
for(int i=first[x];i;i=e[i].next){
int now=e[i].to;
if(e[i^].flow&&d[x]+e[i^].cost<d[now]){
d[now]=d[x]+e[i^].cost;
if(!vis[now]){
if(d[now]<d[q[head]]){head--; if(head<) head=M; q[head]=now;}
else{q[tail++]=now; if(tail>M) tail=;}
vis[now]=;
}
}
}
vis[x]=;
}
return d[S]<mx;
}
int dfs(int x,int a){
if(x==T||a==)return a;
vis[x]=;
int flow=,f;
for(int& i=cur[x];i;i=e[i].next){
int now=e[i].to;
if(!vis[now]&&d[x]==e[i].cost+d[now]&&(f=dfs(now,min(a,e[i].flow)))>){
e[i].flow-=f; e[i^].flow+=f;
ans+=e[i].cost*f; flow+=f;
a-=f;if(a==)break;
}
}
vis[x]=;
return flow;
}
int x[M];
LL sum;
struct pos{int y,k;}qq[M];
bool cmp(pos a,pos b){return a.y<b.y;}
int main()
{
n=read(); m=read();
S=; T=n+m+;
for(int i=;i<=n;i++) x[i]=read(),insert(S,i,,);
for(int i=;i<=m;i++) qq[i].y=read(),qq[i].k=read(),sum+=qq[i].k;
if(sum<n){printf("-1\n"); return ;}
sort(qq+,qq++m,cmp);
for(int i=;i<=m;i++) insert(i+n,T,qq[i].k,);
for(int i=;i<=m;i++){
if(i>) insert(i+n,i+n-,inf,qq[i].y-qq[i-].y);
if(i<m) insert(i+n,i+n+,inf,qq[i+].y-qq[i].y);
}
for(int i=;i<=n;i++){
int k1=; while(qq[k1+].y<=x[i]&&k1<m) k1++;
int k2=m; while(qq[k2-].y>=x[i]&&k2>) k2--;
if(qq[k1].y<=x[i]) insert(i,k1+n,,x[i]-qq[k1].y);
if(qq[k2].y>=x[i]) insert(i,k2+n,,qq[k2].y-x[i]);
}
while(spfa()){for(int i=;i<=T;i++) cur[i]=first[i]; dfs(S,inf);}
printf("%lld\n",ans);
return ;
}
n <= 5000, m <= 5000 的时候就需要dp了
先将洞和老鼠按位置从小到大排一波序
因为老鼠选的洞必然是单调递增的 我们可以考虑dp
f【i】【j】表示前i个洞选j只老鼠
转移方程 f【i】【j】=f【i-1】【k】+(k+1到j 的距离
然后发现是三方的写法 然后就后面可以用单调队列优化dp降一波复杂度
然后就是n方写法了
这里我们每次可以算一下每只老鼠到 第i个洞的 前缀
队列里扔的就是f【j】+(前缀数组)s【j】就好啦
f【i】=q【l】+s【i】就好辣
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=5e3+;
const LL inf=1e15;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>'') {if(c=='-') f=-; c=getchar();}
while(c>=''&&c<='') {ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int l,r,n,m,x[M];
struct pos{int y,k;}e[M];
bool cmp(pos a,pos b){return a.y<b.y;}
LL sum,f[M],s[M];
LL pabs(LL x){return x>=?x:-x;}
struct node{LL v; int pos;}q[M];
int main()
{
n=read(); m=read();
for(int i=;i<=n;i++) x[i]=read();
for(int i=;i<=m;i++) e[i].y=read(),e[i].k=read(),sum+=e[i].k;
if(sum<n){printf("-1\n"); return ;}
sort(x+,x++n);
sort(e+,e++m,cmp);
for(int i=;i<=n;i++) f[i]=inf;
for(int i=;i<=m;i++){
l=; r=;
for(int j=;j<=n;j++) s[j]=s[j-]+pabs(x[j]-e[i].y);
for(int j=;j<=n;j++){
while(l<=r&&q[r].v>=f[j]-s[j]) r--;
while(l<=r&&(j-q[l].pos)>e[i].k) l++;
q[++r].v=f[j]-s[j]; q[r].pos=j;
f[j]=q[l].v+s[j];
}
}printf("%lld\n",f[n]);
return ;
}
汕头市队赛 SRM16 T2的更多相关文章
- 汕头市队赛 SRM1X T2 ——扫描线
绵津见-终 SRM 13 背景 “西瓜也是可以种在海上的!”——绵津见 然而种在海上的西瓜最需要防范的,是时不时会涌向瓜田的阵阵海浪. 幸好,身为海神的绵津见可以释放魔法“水平如镜”来阻止海浪拍打西瓜 ...
- 汕头市队赛 SRM16
T3 C-2 SRM 16 描述 给一个数列,给出两种数字, 询问在多少个非空区间中这两种数字出现次数相同. 输入格式 第一行:一个数字n,q,n表示数列长度,q表示q组询问 第二行n个数字表示数列A ...
- 汕头市队赛 SRM14 T2 最长上升子序列
最长上升子序列 (tree.pas/c/cpp) 128MB 1s 有一个长度为n的序列a[i],其中1到n的整数各自在a[i]中出现恰好一次. 现在已知另一个等长的序列f[i],表示a[i]中以第i ...
- 汕头市队赛 SRM13 T2
这道题很容易想到是二分 但是因为可能会爆LL 所以要加一波特判 #include<cstdio> #include<cstring> #include<algorithm ...
- 汕头市队赛 C KMP codeforces B. Image Preview
汕头市队赛题目传送门 codeforces题目传送门 这道题我的做法是 尝试先往左走然后往右走 或者先往右走然后往左走 然后注意一下枚举顺序就okay啦 #include<cstdio> ...
- 汕头市队赛SRM 20 T2不净的圣杯
不净的圣杯 SRM 20 背景 作为一张BUG级别的卡,官方打算把它修改得人畜无害一些…… 虽然名字还没想好,但是能力大概是对敌方所有单位造成d点伤害,d为自己牌组中所有卡的编号的最大公约数.这无疑是 ...
- 汕头市队赛 yyl杯1 T2
B SRM 05 - YYL 杯 R1 背景&&描述 有一个拥有n个城市的国家.这个国家由n-1条边连接起来.有一天国家发生叛乱.叛军已占领了一些城市.如果叛军占领的城市中,存在两个城 ...
- 汕头市队赛SRM15
T1——czl SRM 15 众所周知,czl家养了一只可♂爱的***(已屏蔽),那只东西很贪吃,所以czl家很多零食仓库,然而这些仓库里有很多老鼠. 为了心爱的***,czl决定点燃纯艾条,用烟熏老 ...
- 汕头市队赛 SRM 07 D 天才麻将少女kpm
这道题放了很久还是回来补了 D 天才麻将少女KPM SRM 07 背景&&描述 天才麻将少女KPM立志要在日麻界闯出一番名堂. KPM上周叒打了n场麻将,但她这次又没控分,而且 ...
随机推荐
- ubuntu设置ssh登陆
转: 默认请况下,ubuntu是不允许远程登陆的.(因为服务没有开,可以这么理解.) 想要用ssh登陆的话,要在需要登陆的系统上启动服务.即,安装ssh的服务器端 $ sudo apt-get ins ...
- 关于 SSH Server 的整体设定
# . 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port # SSH 预设使用 这个 port,您也可以使用多的 port ! # 亦即重复使用 po ...
- Autofac小例子
AutoFac是.net平台下的IOC容器产品.今天学习一下它的使用方法. 1.最简单的使用. public interface ITestDao { string SayHello(); } pub ...
- mybatis <collection>标签 类型为string时无法获取重复数据错误
1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...
- 从底层带你理解Python中的一些内部机制
下面博文将带你创建一个字节码级别的追踪API以追踪Python的一些内部机制,比如类似YIELDVALUE.YIELDFROM操作码的实现,推式构造列表(List Comprehensions).生成 ...
- JavaScript RegExp 身份证、账号密码、email正则
什么是正则表达式 正则表达式是构成搜索模式. 在文本中搜索数据时,可以使用此搜索模式来描述正在搜索的内容. 正则表达式可以是单个字符,也可以是更复杂的模式. 正则表达式可用于执行所有类型的文本搜索和文 ...
- 跳出for循环break和continue的区别
1.break 跳出for循环,结束for循环 如果有两层循环,break只能跳出一层循环 2.continue 跳出本次循环,继续下一条数据的循环
- throw er; // Unhandled 'error' event&Error: ENOENT: no such file or directory,
今天做一个文件上传的项目时, 用express-formidable往硬盘里面存文件时, 报 ENOENT:no such file or directory 原因就是程序不能像别的语言一样不存在就 ...
- 软件工程项目组Z.XML会议记录 2013/10/22
软件工程项目组Z.XML会议记录 [例会时间]2013年10月22日星期二21:00-22:30 [例会形式]小组讨论 [例会地点]三号公寓楼会客厅 [例会主持]李孟 [会议记录]周敏轩 会议整体流程 ...
- Caused by: redis.clients.jedis.exceptions.JedisDataException: WRONGTYPE Operation against a key holding the wrong kind of value
对错误类型key的操作,也就是说redis中没有你当前操作的这个key,而你用这个key去执行某些操作!检查key是否正确