首页 > 代码库 > Bestcoder #92

Bestcoder #92

A

=w=

B

计数题,枚举A、C,算B、D的个数,注意减去重复的

我当时是f[1][n]->f[2][n]->f[3][n]->f[4][n]递推的

C

题意:长为n的字符串仅由‘2‘ ‘3‘组成,有m次交换机会,每次交换相邻的两个位置,求最终可以有多少个"233"子串(n<=100,m<=50)

分析:dp

   首先明确的是,交换只可能交换相邻的2、3

   考虑最终的状态,肯定是一些2,在这些2中间有若干个3,这些2的相对位置和刚开始的字符串相同

   f[i][j][k]表示第i个2,所在新字符串位置是j,用了k次交换,带来的最大233串个数

   那么很明显f[i][j][k]=max(f[i-1][j‘][k]+(j-j‘>=3)) (j==p[i])

        f[i][j][k]=max(f[i-1][j‘][k-abs(p[i]-j)]+(j-j‘>=3)) (j!=p[i])

   这样复杂度是O(n^3 * m)的

   其实仔细分析,对于上一个2,我们需要记录的并不是上一个2和这一个2之间3的确切个数,我们只关心上一个2和这一个2之间的3的个数是0、1或者大于等于2 这三种情况

   因为233、2333、23333对答案的贡献是一样的

   那么这样就应该有O(n^2 * m)的做法

   考虑将所有2单独挑出来,将所有3单独挑出来,那么最后的结果就是2和3的归并

   f[i][j][k][0..2]表示用了i个2,用了j个3,用了k次交换,对应状态是0、1、2情况下最多233子串个数

   t=0表示此时最后一个2后面有足够的3(>=2)

   t=1表示此时最后一个2后面没有3

   t=2表示此时最后一个2后面有1个3

   通过这个进行转移

D

待补

Bestcoder #92