T1:直接广搜。但比赛时以为广搜会超时,于是打了个SPFA,但SPFA反倒超时了。
T2:比赛时用了dg+dp,但得的分还没有dg+dg得的分多。因为dp的循环范围很大。下次做题时不能以为dp一定比dg快,要分析复杂度。
正解:对于每一个数,我们有三种状态:-1(方右边),0(不选)和1(放左边)。我们可以用dfs枚举每一个数的状态,但最多有20个数,3的20次方肯定超时,所以我们可以把序列分开两半来dfs,把每一半的值储存下来,放进两个序列里,关键是怎样根据状态算出方案数,我们可以用中途相遇法。
首先把两个序列按从小到大排序。然后用两个指针l,r指向两个序列的头。之后如下处理:
当a[l]=b[r]时,那么就用一个双重循环查找在a序列中与a[l]相等的值与b序列中与b[r]相等的值,然后每次ans加1.
当a[l]<b[r]时 把l往后移
当a[l]>b[r]时 把r往后移
但这样会出现重复,并且除以2也不能解决。
那我们可以用状压标记,把每次选择的情况压成二进制标记一下(-1和1都当成1,0当成0),判断是否重复,就可以AC啦。
T3:首先设那个长度为n的字符串为a串,则那个危险串为b串。设f[i][j]表示到a串的第i位是b串匹配到了第j位。
40分:b串中没有重复字符
当a串的第i+1位于等于b串的第j+1位时,转移到f[i+1][j+1]。当a串的第i+1位等于b串的第1位时,转移到f[i+1][1],否则转移到f[i+1][0]。
100分:b串中有重复字符
可能会出现以下状况:
a串:abcdabc
b串:abcdabce
i=7,j=7
当a串的第i+1位选d时,按照上述转移方程,转移到f[i+1][0],实际转移到f[i+1][4]。那这样的情况怎样处理呢?
设c[j][k]表示a串的匹配到j位,j+1位k选字符时,最远能匹配到b串的哪个位置。那么我们就可以先求出c数组,然后转态转移方程就变成转移到f[i+1][c[j+1][k]]。