开始了刷题……
T1 题面:给出长度为 m的上升序列A, 请你求出有多少种1……n的排列, 满足A是它的一个LIS. (1<=m<=n<=15)
一开始想到过状压求LIS过程中的单调栈,然而没往下想,去手玩推式子了……然而没推出来……
题解:【状压+3进制】
设F【S,S0】,S,S0为n位二进制,S表示当前已经加了哪些元素,S0表示当前单调栈中的元素,那么枚举最后一个加什么即可。
转移时类似two_pointer扫一遍即可。
注意到S0一定属于S,所以直接用三进制压即可。
有个trick是最后如何统计答案,只要转移时判一下,如果加的元素i在A中,则必须前一个元素出现过才能转移,
然后S0中有m个1即可贡献至答案。
总复杂度是
O(3N∗N)
O
(
3
N
∗
N
)
,貌似会T,只要加个剪枝:如果当前S0中1的个数>m或者当前F值==0 直接conitnue即可。
T2 题面:给出一个正N边形以及其三角剖分,边权为1,Q组询问两点间最短路。
题解:【分治+SPFA】
考虑沿着一条对角线切开多边形,使得点尽量均匀,显然较小的一边至少有
[N3]
[
N
3
]
个点,(证明的话大概是把三角形抽象为节点,转化为一个二叉树,相当于找一条边断开。)然后从对角线的两点跑最短路,对于跨过对角线的点计算答案,同侧的递归做下去即可。最后三角形时判一下即可。
不过这题实现起来很CD,调就更CD了……
过程solve()参数有当前顶点,询问,对角线,然后每次切完都要重新把节点分配,注意要先做右边,防止左边做时下标越界到右边,因为切完后对角线的点会被算两次,所以会多出一些点。
T3 题面:给定一个矩阵,权值为负的话表示一个炮塔,有-1~-4 4个值,代表上下左右四个方向,正的话代表敌人数,每个炮塔可以在攻击范围内选一个位置攻击,贡献为敌人数,要求炮弹路线不能相交。
题解:【最小割】
详见:https://www.cnblogs.com/hongyj/p/8646446.html