SP196 MUSKET - Musketeers 题解
此题为区间动规。
在做题的时候,一看到题目中“按照逆时针顺序围成一圈”的内容,我们就得出这是一个环。既然是环,那我们就把它拆了。由于会有多个答案,我们需要一个个试。所以我们先找到编号为1的醉鬼,趁他不注意,把他劈成两半。再以他的两半为端点,将这个环拉成一条链。注意,因为是区间动规,所以存链的数组需要翻倍。在本题解中,我们将此数组记为 \(a\)。
接下来我们开始研究此区间动规。
状态定义
定义状态 \(f_{i,j}\) 为第 \(i\) 人和第 \(j\) 人是否能相遇。如果能则记为 \(true\),不能则记为 \(false\)。
有的同学就可能要问了:最终不是要让一个人和他自己相遇吗?这很好理解,因为他被分成了位置不相同的两半,而且这个是动规,计算过程中要相遇的可不止他们俩。
边界条件
什么情况下两个人一定会相遇?那肯定是他们俩本来就相邻,也就是 \(j-i=1\) 啦。这时,我们直接标记 \(f_{i,j}=1\)。
状态转移方程
讲了这么久,总算是讲到代码的核心部分了。状态转移方程很简单:
if(f[i][k]&&f[k][j]&&(a[i][k]||a[j][k]))
{
f[i][j]=true;
}
代码就不贴了。