1178 H. Stock Exchange

1178 H. Stock Exchange

题意:
\(2n\)只价值随时间线性变化的股票,即价值为\(a_it+b_i(i=1,\cdots,n)\).初始时刻持有\(1\)\(n\)各一份,在整数时刻可多次交易,每次交易可将一份股票换成在当前价值更低的任意一份,可以同时持有多份同种股票,目标是持有\(n+1\)\(2n\)各一份.求最少所需时间和在此时间下最少所需交易次数.
题解:
首先考虑能否归约到只有初始时刻\(0\)和结束时刻\(T\)进行操作而不增加交易次数.
用调整法:
假设在除初始时刻\(0\)和结束时刻\(T\)的时刻\(t\)有一次\(i\to j\)的交易:

  1. 如果时刻\(t\)\(j\to k\)\(k\to i\)的交易,可以合并并减少一次交易次数.
  2. 如果\(a_i\geq a_j\),那么此后\(i\)的价值会一直比\(j\)高,
    2.1. 如果后来还有\(j\to k\)的交易,那么不妨在后面再进行\(i\to k\)的交易可以减少一次交易次数.
    2.2. 如果后来没有任何\(j\to k\)的交易,说明\(j\)是最后需要持有的股票,不妨等到\(T\)时刻交易而不改变交易次数.
  3. 如果\(a_i< a_j\),和2同理可以向前合并,或调整到\(0\)时刻交易.

因此可以考虑只在时刻\(0\)和时刻\(T\)交易.

然后考虑如何确定结束时刻\(T\)的值.可以证明在时刻\(0\)先将每一份股票都尽可能换成T时刻的最贵股票,接着在时刻\(T\)再替换成对应的目标股票,不会影响正确性:把每一份股票\(i(i\leq i \leq n)\)看成是独立地变成\(j(n+1\leq j \leq 2n)\),如果\(i\)是在时刻\(0\)变成\(j\),也就是说\(i\)能变成的"T时刻的最贵股票"至少在\(T\)时刻比\(j\)贵,因此无论\(i\)是如何变换到\(j\),都可以用上述方法变换.因此可以在\(O(n\log n\log T_{\max})\)的时间求出\(T\).这里的\(T_\text{max}\)其实就是\(b_\text{max}\),因为两条直线的交点横坐标不会超过\(b_\text{max}\).

最后考虑如何求交易次数,可以用费用流解决这个问题,假设给定时刻\(T\),用\(u_i\)表示\(0\)时刻的\(i\)号股票,\(v_i\)表示\(T\)\(i\)号股票.

  1. 源点向\(u_i(1\leq i\leq n)\)连费用为\(0\)流量为\(1\)的边.
  2. 如果\(b_i\geq b_j,u_i\)\(u_j\)连费用为\(1\)流量无限的边.
  3. \(u_i\)\(v_i\)连费用为0流量无限的边.
  4. 如果\(a_iT+b_i\geq a_jT+b_j,v_i\)\(v_j\)连费用为0流量无限的边.
  5. \(v_i(n+1\leq i\leq 2n)\)向汇点连费用为\(0\)流量为\(1\)的边.

但这样会有\(O(n^2)\)条边,需要优化建图,需要修改\(2\)\(4\)的建边.
2'. \(u_i\)会向\(u'_i\)连费用为1流量无限的边.假设存在序列\(\{p_i\}_{i=1}^{2n}\)使得\(b_{p_i}\geq b_{p_{i+1}}\),那么对每个\(i,u'_{p_i}\)\(u'_{p_{i+1}}\)连一条费用为0流量无限的边,如果有\(b_{p_i}=b_{p_{i+1}}\),那么\(u'_{p_{i+1}}\)也要向\(u'_{p_i}\)连一条费用为0流量无限的边,最后\(u'_i\)\(u_i\)一条费用为0流量无限的边.
同样,类似地修改\(4\).边数就会变成\(O(n)\)条边.
在实现中,可以使用SSPA费用流算法达到\(O(fT(|V|,|E|))\)的复杂度,其中\(f\)是总流量,\(T(|V|,|E|)\)是求单源最短路径的复杂度.如果使用Dijkstra算法就可以达到\(O(n^2\log n)\)的复杂度.注意到边权必为\(0\)\(1\),因此可以使用01BFS算法达到\(O(n^2)\)的复杂度.
代码(Dijkstra)
代码(01BFS)

猜你喜欢

转载自www.cnblogs.com/Heltion/p/12344654.html
今日推荐