题目大意
现在你要写出m个长度为n的二进制序列,有一些形如“第i个的第j位必须为x”的限制
对于后面的二进制要>=前面的任意一个二进制
题解
每一个二进制只和和前面的一个二进制有关系,所以有一个很暴力的做法,就是状压前面的一个二进制然后枚举当前的二进制再判断是否合法,这样是 22n 2 2 n 级别的
如何更进一步
我们考虑从本质上思考如何判断两个二进制哪一个大哪一个小
前面的若干位相同,某一位其中一个是0一个是1,后面的位任意
换一种思路呢?
一个二进制>=另一个二进制,这个二进制肯定可以表示成另一个二进制的某一些1前移(可以没有),移完之后再在一些是0的地方换成1(也可以不换)
结合这两种思路我们可以设出一个神奇的dp
f[i][j][S]表示做到第i个二进制,前j位和S相同的方案数(第i个二进制是一位一位放的,所以也可以理解成第i个二进制放了j个0/1)
如果下一位我们要选的和S一样就直接转移到f[i][j+1][S]
如果下一位我们想拿0,但是S的下一位是1那就不合法了
如果下一位我们想拿1,但是S的下一位是0呢
看一看上面,我们这时就有两种方法(前移/添加),并且上面已经说明要先尽量前移,无法前移再考虑添加,所以看一看S后面有没有可以往前移的1,有就前移没有就添加
最后把f[i][n][S]转移到f[i+1][0][S]就可以了