zoukankan      html  css  js  c++  java
  • XSY3244 10.31 D

    XSY3244 10.31 D

    题意:

    ​ 数轴上有(N)只老鼠(M)个洞,每个洞有一个容量,求所有老鼠进洞的最小代价。((N,Mleq1000000),时限(2s))

    题解:

    ​ 被代爷的前两道题卡得醉生梦死,场上根本没看这题。。。

    ​ 十万的档显然可以(dp),加个线段树什么的就可以了。

    ​ 对于100%的数据,上面的那个(dp)已经没用了,代爷给的做法是正反贪心,让每只老鼠贪心选择左/右最近的洞。对于每只老鼠,这两个洞正好是它最终决策会去的洞。然后把老鼠和每一个可能有老鼠进的洞一起摆在数轴上,做一遍(dp)。状态(f_{i,j})表示搞到第(i)个点,老鼠比洞多(j)个,转移挺简单的。这个(dp)相较上面的那个,优点在于它可以直接利用指针跳(O(1))转移。时空复杂度都是线性的。

    ​ 场上还有人想出了另一种做法。这是我代码的做法。

    ​ 我们建出一个模型:

    • 对于老鼠和洞,我们分别用两个大根堆(M,H)储存,按位置。

    • 将老鼠和洞按位置排序。

    • 如果当前处理的是老鼠,那就取(H)堆顶,钦定它进这个洞,这个容量(-1)并且在以老鼠为镜面,这个洞反射过去的地方往(M)堆里插入一只老鼠,更新答案。

    • 如果当前处理的是洞,那就让(M)堆中所有坐标比它大的老鼠滚进这个洞(显然比老鼠在当前洞内更优),但是这不一定最优,所以我们要建立反悔机制:(Delta = 当前洞的坐标-这只老鼠的坐标),在(当前洞坐标当前洞坐标+ Delta)的地方新建容量为一的洞;更新答案,如果处理完所有之后当前洞还有剩余的容量,就把它扔进堆里。想一想,为什么。

      ​代码:

      #include<queue>
      #include<cstdio>
      #include<cstring>
      #include<iostream>
      #include<algorithm>
      #define fo(i,l,r) for(int i=l;i<=r;i++)
      #define of(i,l,r) for(int i=l;i>=r;i--)
      #define fe(i,u) for(int i=head[u];i;i=e[i].next)
      using namespace std;
      typedef long long ll;
      typedef pair<ll,int> pli;
      #define P(a,b) make_pair(a,b)
      inline void open(const char *s)
      {
      	#ifndef ONLINE_JUDGE
      	char str[20];
      	sprintf(str,"in%s.txt",s);
      	freopen(str,"r",stdin);
      //	sprintf(str,"out%s.txt",s);
      //	freopen(str,"w",stdout);
      	#endif
      }
      inline ll rd()
      {
      	static ll x,f;
      	x=0;f=1;
      	char ch=getchar();
      	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1ll;
      	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10ll+ch-'0';
      	return f>0?x:-x;
      }
      const int N=1000010;
      int n,m;
      ll ans=0;
      pli a[N<<1];
      priority_queue<ll>M;
      priority_queue<pli>H;
      
      inline void gaoM(pli x)
      {
      	ll res=1000000000000000ll;
      	if(!H.empty()){
      		pli y=H.top();H.pop();
      		res=x.first-y.first;
      		if(--y.second)H.push(y);
      	}
      	M.push(x.first+res);
      	ans+=res;
      }
      inline void gaoH(pli x)
      {
      	while(x.second&&!M.empty()&&M.top()>x.first){
      		ll y=M.top();M.pop();
      		ll res=x.first-y;x.second--;
      		ans+=res;H.push(P(x.first+res,1));
      	}
      	if(x.second)H.push(x);
      }
      
      int main()
      {
      	open("c");
      	n=rd();m=rd();
      	fo(i,1,n)a[i].first=rd(),a[i].second=-1;
      	ll s=0;
      	fo(i,1,m)a[n+i].first=rd(),a[n+i].second=rd(),s+=a[n+i].second;
      	if(s<n)return puts("-1"),0;
      	sort(a+1,a+n+m+1);
      	fo(i,1,n+m){
      		if(a[i].second==-1)gaoM(a[i]);
      		else gaoH(a[i]);
      	}
      	printf("%lld
      ",ans);
      	return 0;
      }
      
      
  • 相关阅读:
    ubuntu18.04 切换python版本
    chart
    tox -e py27报错
    ubuntu 18.04配置静态ip,解决无法上网问题,解决resolv.conf配置文件被覆盖
    ubuntu 18.04输入法问题
    openstack 王者归来学习笔记
    nova client和nova restfull api区别
    nova-api nova-compute 启动服务的时候有的没有加配置文件有的加了
    go语言基本语法
    【转】 Docker和CI/CD实战
  • 原文地址:https://www.cnblogs.com/JackyhhJuRuo/p/9884190.html
Copyright © 2011-2022 走看看