草草写完的,写的不太好,望谅解
移动"哨兵棋子"
题面+数据规模
一条数轴有\(N\)个棋子,每个棋子可以占据一个整数位置。\(N\)个棋子目前位于不同的整数位置,现在你想要移动它们以便它们占据N个连续位置(例如,位置\(5,6,7,8\))。当前所有棋子中位置最小或者位置最大的棋子,称为“哨兵棋子”。每一次,你只能移动“哨兵棋子”。你可以把“哨兵棋子”移动到当前任何未占用的整数位置,前提是在这个新位置该棋子不再是一个“哨兵棋子”。请确定使得\(N\)个棋子最终占据连续的\(N\)个位置的最小移动次数和最大移动次数。
棋子的数量:3 <= N <= 100000
棋子的位置ai:[1,1000000000]
题解
根据题意,我们可以发现,每一次的移动都会使最远的两个棋子的距离变小,如果要让移动步数尽可能多,那么要让距离缩小的速度变小,这就说明只要有间隔,就尽可能都走一遍。
看看下面这个例图:
...O..O.O...O...OO.....O..
我们走第一步,我们要让空缺尽可能多,那么我们移动左边的棋子,变成了这个样子:
......OOO...O...OO.....O..
----I
接下来,我们要把所有可以走的空缺都走,幸运的是,剩下的空缺其实都是可以走到的。
移动的方法是“滚”,每一步都把最左边的一个棋子移到离它最近的空格处。
那么最大值可以用下边的方法求出:
\(\sum\limits_{i=2}^n (a_i-a_{i-1}) - \min\{a_2-a_1,a_n-a_{n-1}\}\)
接下来解决最小值,由于移动完成后的样子应该是类似这个样子的:
.....OOOOOOO....
由连续n个棋子组成的
那么我们可以枚举完成后的n各个位置的起始点。比如我们把它放在这个位置:
......OOO...O...OO.....O..
[ ]
这个区间里面有三个点,剩下四个点要填,我们脑子稍微转一转,我们得到下面的移动方法:
......OOO...O...OO.....O..
-------I
.......OO...OO..OO.....O..
I------------
.......OO..OOO..OO........
I-------
.......OO.OOOO..O.........
I-------
.......OOOOOOO............
这个的确是移动步数最小的方法,仔细观察,可以发现,只要我们把要到达的区间的两端都各使用一步(如果已经被填上就不需要了),剩下的就一步一个空,总共就需要\(n-sum(l,r)\)步,\(sum(l,r)\)表示本身已经在区间\([l,r]\)中的棋子个数。显然最小移动步数就是所有中最小的\(n-sum(l,r)\)。
在实现的时候,我们可以枚举区间的左端点,用二分找到sum值,或者枚举区间的右端点,然后使用单调队列得到在这个区间中最左边的棋子的位置。
但问题是,位置的枚举可能会超时,但是我们可以发现,很多的\(sum(l,r)\)值其实是一样的,从左到右扫过去,如果两个相邻的\(sum(l,r)\)相等,就说明没有失去任何棋子,或者没有加入任何棋子。那么我们可以只枚举每个棋子的位置作为左端点(或者右端点),这样既不会考虑少可能的情况,效率也快了不少。
树与图
题面+数据规模
最近有人发明了一款新游戏。给定具有N个顶点的连通无向图和具有N个节点的树,尝试以下列方式将该树放置在图上:
- 树的每个节点与图的顶点对应。即每个节点对应一个顶点,每个顶点对应一个节点。
- 如果树的两个节点之间存在边,则图中的相应顶点之间也必须存在边。
现在想知道有多少不同的放置方案,答案模1000000007
。
1<=n<=14
题解
idea 1
我们先给这棵树强制地弄一个根\(root=1\)。
考虑树形dp,我们用\(f(u,mu, S)\)表示树中的点\(u\),映射到图中的点\(mu\),映射子树\(T_u\)所使用的集合为\(S\),且合法的方案数。
我们用\(G(u, v)\)表示途中点u和点v中是否存在边。那么:
\(f(u,mu, S)=\prod\limits_{v\in son_u} \sum\limits_{G(mu,mv)} \sum\limits_{S'\subset S} f(v,mv,S)\)
那么最终答案就是\(\sum\limits_{mu=1}^n f(u,i,\{1\ to\ n\})\)
时间复杂度极高,不过好在LGJ仁慈,凭信仰可过。
idea 2
我们使用容斥原理,首先枚举一个图中的集合\(V\),我们要将所有的树上节点都映射到这个集合中,可以将多个树上节点映射到一个图上节点中,只要这个树上节点映射的点和该节点的父节点映射的节点有一条边就好了。
显然,对于\(n-|S|\)为偶数的情况,我们要加入总答案,否则减去。
接着,我们需要求出每一个集合对应的方案数:
用\(f(u,mu)\)表示点\(u\)映射到\(mu(mu\in V)\)的\(T_u\)的映射方案。显然得到:
\(f(u,mu) = \prod\limits_{v\in son_u}\sum\limits_{mv\in V,G(mu,mv)} f(v,mv)\)
那么一个集合\(V\)的方案数是\(\sum\limits_{mu\in V} f(1,mu)\)
原文地址:https://www.cnblogs.com/juruohjr/p/10660629.html