2019暑期集训 - Day 12

臭题目,第一题害我调一下午,第二题害我调一晚上,第四题又害我调一下午





概述

提高 B 组
4题:T0 , T1 , T2 , T3
120/400 分
15/153 名


T0 少女觉

WA 0/100 分

Description

在幽暗的地灵殿中,居住着一位少女,名为古明地觉。
据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力——读心。
掌控人心者,可控天下。

咳咳。
人的记忆可以被描述为一个黑块 ( \(B\) ) 与白块 ( \(W\) ) 的序列,其中情感值被定义为序列中黑块数量与白块数量之比。
小五口在发动读心术时,首先要解析人的记忆序列,因此,需要将序列分割为一些段,并且要求每一段记忆序列的情感值都相等。
下面给出两个例子:
\(BWWWBB \to BW + WWBB\ \ (Ratio=1:1)\)
$WWWBBBWWWWWWWWWB \to WWWB + BBWWWWWW + WWWB\ \ (Ratio=3:1) $
现在小五手上有一个人的记忆序列,她想要知道,如何将手中的记忆序列分成尽可能多的段呢?

Input

第一行包含一个正整数 \(T\) ,代表数据组数。
对于每一组测试数据,第一行包含一个正整数 \(N\)
接下来 \(N\) 行描述一个序列,每行包含一个正整数 \(K\) 和一个大写字母 \(C\) ,表示序列接下来有连续 \(K\) 个颜色为 \(C\) 的方块。

Output

对于每组测试数据输出一行一个正整数,表示最多分成的段数。

Sample Input

3
3
1 B
3 W
2 B
4
3 W
3 B
9 W
1 B
2
2 W
3 W

Sample Output

2
3
5

Hint

对于10% 的数据, \(n\leq15\)
对于20% 的数据, \(n\leq500\)
另有30% 的数据, \(K=1\)
另有30% 的数据, \(K\leq50\)
对于100% 的数据, \(N\leq10^5\) ,序列长度不超过 \(10^9\)
保证对于全部测试点,输入文件行数不超过 \(2500000\)

Solution

暴力出奇迹

贪心暴搜
因为整体比例是固定的,所以我们可以用总的 \(B\)\(W\) 的格数相除得到比值,这个比值就应作为每段中 \(B\)\(W\) 的比值。
很容易证明,对于一个记忆序列的最优解,应当每段尽量早的分出去,也就是说,没碰到一次可以分出一段的情况,就该分出这一段。所以这个题目满足贪心策略。
考虑到序列长度可能很大,我们可能无法一个一个方块枚举计算,所以我们存储连续相同颜色的格子数。
比如对于 \(BBBWB\) 我们存储为 \(3,1,1\) ;对于 \(WWWBBBWWWWWWWWWB\) ,我们存储为 \(0,3,3,9,1\)(默认以 \(B\) 开始,次样例中第一个 \(0\) 代表最开始有 \(0\)\(B\))。
从第一个数开始向后推,每次更新上次分段的结束点之后到此位置中 \(B\)\(W\) 的格数,然后判断加入这一串格子中的一部分后是否能分为一段(即能否达到需要的比值),如果能,则将这部分分为一段,记录 ans++
最后答案即分段数就是 ans

T1 灵知的太阳信仰

WA 0/100 分

Description

在炽热的核熔炉中,居住着一位少女,名为灵乌路空。
据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量——核能。
核焰,可融真金。

咳咳。
每次核融的时候,空都会选取一些原子,排成一列。然后,她会将原子序列分成一些段,并将每段进行一次核融。
一个原子有两个属性:质子数和中子数。
每一段需要满足以下条件:

  1. 同种元素会发生相互排斥,因此,同一段中不能存在两个质子数相同的原子。
  2. 核融时,空需要对一段原子加以防护,如果这段原子的中子数最大为 \(x\) ,那么需要付出 \(x\) 的代价建立防护罩。

$ $
求核融整个原子序列的最小代价和。

Input

第一行一个正整数 \(N\) ,表示原子的个数。
接下来 \(N\) 行,每行两个正整数 \(p_i\)\(h_i\) ,表示第 \(i\) 个原子的质子数和中子数。

Output

输出一行一个整数,表示最小代价和。

Sample Input

5
3 11
2 13
1 12
2 9
3 13

Sample Output

26

Hint

对于20% 的数据, \(1\leq n\leq 100\)
对于40% 的数据, \(1\leq n\leq 1000\)
对于100% 的数据, \(1\leq n\leq 10^5\)\(1\leq p_i\leq n\)\(1\le h_i\le 20000\)

Solution

DP 累死人

这题使用贪心策略肯定是有问题的,比如如下数据点:

3
1 1
2 5
1 3

使用贪心策略尽可能取每个原子时,这个点的答案为 \(5+3=8\) ,而正解答案应为 \(1+5=6\)

考虑使用动态规划完成,记 \(f_i\) 代表取前 \(i\) 个原子所需的最小代价,\(s_{i,j}\) 代表第 \(i\) 个原子到第 \(j\) 个原子的中子数最大值。
记录 \(l_i\) 代表从第 \(i\) 个原子开始向左能取到的最左边的位置,即 \(l_i\)\(i\) 这两个位置间没有重复质子数,但 \(l_i-1\)\(i\) 这两个位置间有重复质子数。
很容易得到, \(f_i=f_j+\min(s_{j+1,i})\) ,即前 \(j\ (j\ge l_i)\) 个数先分段,最后加上从 \(j\)\(i\) 这一段。
然而,这样做时间复杂度 \(O(N^2)\) ,会 TLE ,所以考虑如何优化。
用一个单调递减的单调队列,维护 \(s_{l_i,i}\sim s_{i,i}\) ,即对于位置 \(i\) 所有可能取值 \(j\)\(s_{j+1,i}\) 的值。所以每次队首的位置 \(< l_i\) 时,就把它踢出队列,如果队尾的 \(s\)\(\le h_i\) ,将队尾元素弹出,并加入 \(h_i\) 。这是因为对于位置 \(i\) 即其之后,既然队首元素的位置 \(<l_i\) ,所以从这个位置开始根本取不到第 \(i\) 个原子,对于更新 \(f_i\) 没有意义;如果队尾的 \(s\)\(\le h_i\) ,则完全可以使用 \(h_i\) 更新以后的 \(f\) 值,队尾的 \(s\) 值也没有任何意义了。
这样,每次更新 \(f_i\) 时,只用队列里的 \(s\) 值更新就可以了。
最后的答案即为 \(f_n\)

T2 多段线性函数

AC 100/100 分

Description

\(n\) 个变量 \(x_1,x_2,\cdots,x_n\) ,满足 \(x_i\in \mathbb{R}\) 。对于每个变量,都有一个限制: \(x_i\in [l_i,r_i]\) 。人员两个变量的取值不互相影响。
小Z 给你一个多段线性函数:
\(\large{f(y)=\sum_{i=1}^{n}|y-x_i|}\)
定义这个函数的局部最小值 \(f_{\min}(y_0)\) 为:当 \(y\) 取某个值 \(y_0\) 时,存在一种 \(x_i\) 的取值方案使得函数值为 \(f_{\min}(y_0)\) ,且对于所有的 \(x_i\) 的取值方案,都有 \(f(y_0)\geq f_{\min}(y_0)\)
定义这个函数的全局最小值 \(f_{\min}\) 为:存在某个 \(y=y_0\) ,使得 \(f_{\min}(y_0)=f_{\min}\) ,且对于所有的 \(y\) ,都有 \(f_{\min}(y)\ge f_{\min}\)
你的任务是求出 \(y\) 的取值范围 \([L,R]\) ,使得对于所以的 \(y\in [L,R]\) ,都有 \(f_{\min}(y)=f_{\min}\)
可以证明 \([L,R]\) 是答案的一般形式,也就是说不存在多段的 \(y\) 满足题意。如果 \(y\) 仅能取一个值 \(z\) ,令 \(L=R=z\)

Input

第一行包含一个正整数 \(n\)
接下来 \(n\) 行,每行两个非负整数 \(l_i,r_i\)

Output

输出一行两个自然数,用空格隔开,依次为 \(L,R\)

Sample Input

5
1 3
2 3
3 5
5 5
6 7

Sample Output

3 5

Hint

Solution

口胡出正解

做法很简单,一起记录 \(l_i,r_i\) , sort ,输出中位数即最中间的两个数,没了。
至于证明 . . .
考虑另一个数

\(\large{s_t=\min(\ \sum_{i=1}^{n}2|t-x_i|+r_i-l_i}\ )\)

很容易得到 \(|t-x_i|\) 的值要么为 \(0\ (l_i\le t\le r_i)\) ,要么为 \(l_i-t\ (t<l_i)\)\(t-r_i\ (t>r_i)\) 。而 \(2|t-x_i|+r_i-l_i\) 则一定等于 \(|t-l_i|+|t-r_i|\) ,即

\(\large{s_t=\min(\ \sum_{i=1}^{n}|t-l_i|+|t-r_i|}\ )\)

可以通过分类讨论的思想证明:

$\ \ \ \ 2|t-x_i|+r_i-l_i $

\(=0+r_i-l_i\)
\(=|t-l_i|+|t-r_i|\)
\(\ \ \ \ \ (l_i\le t\le r_i)\)

\(=2l_i-2t+r_i-l_i\)
\(=(r_i-t)+(l_i-t)\)
\(=|t-l_i|+|t-r_i|\)
\(\ \ \ \ \ (t<l_i)\)

\(=2t-2r_i+r_i-l_i\)
\(=(t-r_i)+(t-l_i)\)
\(=|t-l_i|+|t-r_i|\)
\(\ \ \ \ \ (t>r_i)\)

用数轴和绝对值的几何意义更好理解。

图中浅灰色代表算过一次,深灰色代表算过两次。
可以发现,两个计算的结果完全相同。

并且,我们发现,公式中,比原式多出的系数 \(2\)\(\sum_{i=1}^{n}r_i-l_i\) 都是定值,不影响结果的大小比较。也就是说,当 \(s_t=s_{\min}\) 时, \(f_{\min}(t)=f_{\min}\) 。所以,我们只需求满足前式 \(s_t=s_{\min}\)\(t\) 的取值范围就行了。

现在,我们把所有的 \(l_i,r_i\) 列入集合 \(d\) 中,问题变成了求

\(\large{\min(s_t=\ \sum_{i=1}^{2n}|t-d_i|}\ )\)

即将 \(d\) sort 后的中位数为 \(t\) 的取值范围。

T3 DY引擎

WA 20/100 分

Description

BOSS 送给小唐一辆车。小唐开着这辆车从 PKU 出发去 ZJU 上课了。
众所周知,天朝公路的收费站超多的。经过观察地图,小唐发现从PKU出发到ZJU的所有路径只会有 \(N\ (2\le N\le 300)\) 个不同的中转点,其中有 \(M\ (\max(0,N-100) \le M\le N)\) 个点是天朝的收费站。 \(N\) 个中转点标号为 \(1,2,\cdots ,N\),其中 \(1\) 代表 PKU , \(N\) 代表 ZJU 。中转点之间总共有 \(E\ (E\le 50,000)\) 条双向边连接。
每个点还有一个附加属性,用 \(0/1\) 标记, \(0\) 代表普通中转点, \(1\) 代表收费站。当然,天朝的地图上面是不会直接告诉你第 \(i\) 个点是普通中转点还是收费站的。地图上有 \(P\ (1\le P\le 3000)\) 个提示,用 \([u, v, t]\) 表示: \([u, v]\) 区间的所有中转点中,至少有 \(t\) 个收费站。数据保证由所有提示得到的每个点的属性是唯一的。
车既然是 BOSS 送的,自然非比寻常了。车子使用了世界上最先进的 DaxiaYayamao 引擎,简称 DY 引擎。 DY 引擎可以让车子从 \(U\) 瞬间转移到 \(V\) ,只要 \(U\)\(V\) 的距离不超过 \(L\ (1\le L\le 1000000)\),并且 \(U\)\(V\) 之间不能有收费站(小唐良民一枚,所以要是经过收费站就会停下来交完钱再走)。
DY 引擎果然是好东西,但是可惜引擎最多只能用 \(K\ (0\le K\le 30)\) 次。

Input

第一行有 \(6\) 个整数 \(N,M,E,P,L,K\) 分别代表: \(N\) 个中转点, \(M\) 个收费站, \(E\) 条边, \(P\) 个提示, DY 引擎的有效距离 \(L\) , DY 引擎的使用次数 \(K\)
接下去 \(E\) 行,每行有 \(3\) 个整数 $u,v,w\ (1\le u,v\le N;1\le w\le 1000000)\ $ 表示: \(u\)\(v\) 之间有一条长度为 \(w\) 的双向边。
接下去 \(P\) 行,每行有 \(3\) 个整数 \(u,v,t\ (1\le u\le v\le N; 0\le t\le u-v+1)\) 表示: \([u, v]\) 标号区间至少有 \(t\) 个收费站。

Output

输出一个整数,表示小唐从 PZU 开到 ZJU 用的最短距离(瞬间转移距离当然是按 \(0\) 来计算的)。

Sample Input

6 2 6 2 5 1
1 2 1
2 3 2
3 6 3
1 4 1
4 5 2
5 6 3
2 5 2
4 6 2

Sample Output

1

Hint

【样例解释】

\(4,5\) 是收费站。 \(1\to 2(1)\to 6(1)\)

【数据范围】

对于30% 的数据保证:
\(2\le N\le 30\ ,\ \max(0,N-10) \le M\le N\ ,\ 0\le k\le 10\)
对于100% 的数据保证:
\(2\le N\le 300\ ,\ \max(0,N-100) \le M\le N\ ,\ E\le 50000\ ,\ 1\le P\le 3000\ ,\ 1\le L\le 1000000\ ,\ 0\le K\le 30\)

Solution

有必要把两个小题硬凑在一起吗?

差分约束 + 分层最短路
把每个收费站的提示当做一个不等式,因为题目保证只有唯一解,所以用差分约束解出每个点是否为收费站 ( SPFA ,最短路\(\times1\)
枚举任意两个点间是否可以瞬移 ( Floyd ,最短路\(\times 2\)
把图复制为 \(K+1\) 层,分别代表已开 \(0,1,2,\cdots,K\) 次挂对应的那一层,每两层的分别某个点如果可瞬移(上已枚举哪两个点可以互相瞬移),就在它们间连一条权值为 \(0\) 的边用来开挂。
\(1\) 开始跑一边最短路(最短路\(\times 3\)),然后对每层第 \(n\) 个点的 \(dist\)\(\min\) ,结果即为答案。

最后也就 \(3\) 遍最短路, \(200\) 行左右吧。





差分约束

如果一个系统由 \(n\) 个变量和 \(m\) 个约束条件组成,形成 \(m\) 个形如 \(a_i-a_j\le k\) 的不等式( \(i,j∈[1,n]\)\(k\)为常数),则称其为差分约束系统( system of difference constraints )。
求解差分约束系统,可以转化成图论的单源最短路径(或最长路径)问题。
观察 \(x_j-x_i\le b_k\) ,会发现它类似最短路中的三角不等式 \(d[v]\le d[u]+w[u,v]\) ,即 \(d[v]-d[u]\le w[u,v]\) 。因此,以每个变量 \(x_i\) 为结点,对于约束条件 \(x_j-x_i\le b_k\) ,连接一条边 \((i,j)\) ,边权为 \(b_k\) 。我们再增加一个源点 \(s\) , \(s\) 与所有定点相连,边权均为 \(0\) 。对这个图,以 \(s\) 为源点运行 Bellman-ford 算法(或 SPFA 算法),最终 \(d[ i]\) 即为一组可行解。

posted @ 2019-12-27 17:00  imzzy  阅读(33)  评论(0)    收藏  举报