Portal --> who knows ==

Description

  数轴上面有一些洞,有一些老鼠,每个洞有一个容量限制,一只位于\(x\)的老鼠进到位于\(y\)的洞要花费\(|x-y|\)的代价,问所有老鼠都进洞的最小代价,如果没有合法方案输出\(-1\)

  数据范围:\(n,m<=10^6,1<=c_i<=n\),其中\(c_i\)表示每个洞的容量,\(0<=\)位置\(<=10^9\)

  

Solution

  这题的话。。长得像一个dp。。但是如果直接莽显然是不行的。。

​  注意到一个点:将洞和老鼠都按照位置排序,最优方案中进入同一个洞的老鼠一定是一段连续的区间,那么记\(f[i][j]\)表示前\(i\)个洞,前\(j\)只老鼠已经进洞了的最小代价,转移的话:

\[f[i][j]=min(f[i-1][k]+sum[j]-sum[k])
\]

  其中\(k\)的枚举范围是\([j-c[i],j]\),\(sum[j]\)表示的是\(\sum\limits_{p=1}^j|rat_p-hole_i|\)

​  那么线段树优化一下就有一个\(O(nmlogn)\)的做法(然而实际上好像直接单调栈什么的搞一搞除去排序就是\(O(nm)\)了)

​   

  然后注意到这个dp是没有前途的。。(没有办法继续优化了),所以换一种思路

  不选择分开考虑,而是选择将所有的老鼠和洞放在一起,这里有一种很妙的用堆的做法(疯狂orzhwc),用两个堆分别维护老鼠和洞

  我们将老鼠和洞放在一条线上,一只老鼠要么会被丢到前面,要么会被丢到后面,那么我们从左往右扫,考虑如果扫到一只老鼠,我们先无脑将它丢到它前面的离它最近的有容量的洞里面,更优情况的替换我们放在扫到一个洞的时候处理

  扫到一个洞的时候,如果说有只当前被丢到前面洞里的老鼠丢到这个洞里面会比当前更优,那么就把这只老鼠丢进来,更新当前答案,具体的判断方式是:我们将前面的那个洞的位置以当前老鼠为对称轴对称过来,如果说对称过来得到的位置比当前洞的位置更大,那么说明当前洞更优

  具体处理的话就是用一个堆维护被丢进前面的洞里的老鼠对应的洞的对称值(也就是\(rat+hole\),其中\(rat\)表示这只老鼠的位置,\(hole\)表示对应洞的位置),然后如果堆顶的那个老鼠不能被当前这个洞更新,那肯定也不能被后面的洞更新了,所以直接弹掉

  然而这里有一个问题,当前的决策放在后面不一定是最优的,也就是说有的老鼠当前可能丢到后面比较优,但是放在全局可能就是丢到前面比较优了,为了应对这种情况,我们需要一个撤销操作,具体的实现就是,如果说在扫到一个洞的时候,我们用这个洞更新了某只老鼠,那么对应的我们要多加一个相当于撤销操作的洞到洞的堆里面,撤销的具体含义就是:如果说当前的老鼠选了一个撤销洞,那么就相当于令被撤销洞更新的老鼠重新回到更新前的洞里,并且将当前的老鼠丢到这个洞里

​  实现上的话,假设撤销洞位置为\(y\),被撤销洞更新的老鼠\(A\)在更新前在的洞是\(x\),\(delta\)是该老鼠选\(y\)比选\(x\)优多少,那么撤销洞的位置就应该为\(y+delta\),并且容量为\(1\),之所以这么设是因为:如果说当前的老鼠\(B\)选了这个洞,那么\(ans\)会被加上\(rat_B-(y+delta)\),也就是相当于将\(delta\)去掉(老鼠\(A\)回到\(x\)),然后再加上老鼠\(B\)选\(y\)这个洞的贡献

  然后一路扫过去就好了ovo

  

  mark:撤销洞的思路很有意思,mark一下

  

  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define ll long long
#define Pr pair<ll,int>
#define mp make_pair
using namespace std;
const int N=1000010;
const ll inf=1LL<<60;
struct Data{
int p,c,ty;
friend bool operator < (Data x,Data y){
return x.p==y.p?x.ty<y.ty:x.p<y.p;
}
}a[N*2];
priority_queue<Pr> hole;
priority_queue<ll> rat;
int n,m,cnt;
ll ans;
void solve_rat(int i){
ll w=inf;
Pr tmp;
if (!hole.empty()){
tmp=hole.top(); hole.pop();
w=a[i].p-tmp.first;
--tmp.second;
if (tmp.second)
hole.push(tmp);
}
rat.push(w+a[i].p);
ans+=w;
}
void solve_hole(int i){
ll delta;
while (a[i].c&&!rat.empty()&&a[i].p<rat.top()){
delta=a[i].p-rat.top(); rat.pop();
ans+=delta;
--a[i].c;
hole.push(mp(a[i].p+delta,1));
}
if (a[i].c)
hole.push(mp(a[i].p,a[i].c));
}
void solve(){
for (int i=1;i<=cnt;++i)
if (a[i].ty==0)
solve_rat(i);
else
solve_hole(i);
printf("%lld\n",ans);
}
void print(Pr x){printf("(%d,%d)\n",x.first,x.second);} int main(){
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
int x,y;
ll sum=0;
scanf("%d%d",&n,&m);
cnt=0;
for (int i=1;i<=n;++i) scanf("%d",&a[++cnt].p),a[cnt].ty=0;
for (int i=1;i<=m;++i){
scanf("%d%d",&x,&y);
if (!y) continue;
a[++cnt].p=x; a[cnt].c=y; a[cnt].ty=1;
sum+=y;
}
if (sum<n){printf("-1\n"); return 0;}
sort(a+1,a+1+cnt);
solve();
}

【noip模拟】D(==)的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

  10. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

随机推荐

  1. VMware vSphere 6.0 安装及管理手册

    目录 1. VMWARE_VSPHERE安装 1.1. 底层ESXI 安装步骤 1.2. VCENTER安装步骤 1) 准备vCenter安装环境 2) vCenter安装步骤 2. VMWARE_V ...

  2. django orm 操作表

    django orm 操作表 1.基本操作 增 models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs inser ...

  3. Linux虚拟机安装教程

    必备组件: vmware(程序主题) 链接:https://pan.baidu.com/s/14OplOGOQTVAnf0iDqgDhDQ 提取码:jape centos(Linux系统) 链接:ht ...

  4. 亚马逊的客户服务和承诺 - Delay in shipping your Amazon.com order - Missed Fulfillment Promise

    We encountered a delay in shipping your order. We apologize for the inconvenience. Since your packag ...

  5. flume handler

    1.classpath classpath中需要这两项:Flume Agent configuration file and the second are the Flume client jars ...

  6. C++ 类 构造函数 constructor

    构造函数 当定义了一个整型变量: int a; 这会申请了一块内存空间来存储a,但是这块内存中原本有数据的,可能是任何值,这不是你所希望的,若你就希望a表示1,所以要把a的值赋值为1. ; 例: #i ...

  7. "Hello World!"团队负责人领跑衫感言

    时间:2017年12月7日 团队名称:“Hello World!” 团队项目:空天猎 团队成员:陈建宇(项目负责人).刘淑霞.黄泽宇.方铭.贾男男.刘耀泽.刘成志 感言正文: 记<软件工程> ...

  8. 个人作业Week7

    1.在做个人项目的时候,由于很久都没有写这么大的程序了,对程序的感觉还没有恢复,因此,没能完全完成个人项目.现在回去看个人项目的代码(针对完成的代码来看),完全就是一个大泥球,代码的结构性太差,基本上 ...

  9. alpha版postmortem 报告

    一.团队开发存在的问题 此次会议我们团队中每个成员都仔细思考并提出了团队在这一阶段存在的问题,主要如下: 1.前期任务规划.分配不合适: 2.个人对认领任务模块完成度.了解度不够: 3.个人学习意识. ...

  10. mysql 官方集群

    一.环境准备(Centos7,mysql-cluster-gpl-7.5.6-linux-glibc2.5-x86_64.tar.gz) 卸载以前安装的Mysql 或者 mariadb yum -y ...