SOS DP

learn from blog of 海边拾贝的言

definition

sos: sum over subsets
target: F ( m a s k ) = ∑ i ∈ m a s k A ( i ) F(mask) = \sum_{i \in mask} A(i) F(mask)=imaskA(i)
linked to FWT (need a complement), fellow are definition of FWT
F W T   o r FWT\ or FWT or : F W T ( k ) = ∑ i   o r   j = k A ( i ) ∗ B ( j ) FWT(k) = \sum_{i\ or\ j = k} A(i) * B(j) FWT(k)=i or j=kA(i)B(j)
F W T   a n d FWT\ and FWT and : F W T ( k ) = ∑ i   a n d   j = k A ( i ) ∗ B ( j ) FWT(k) = \sum_{i\ and\ j = k} A(i) * B(j) FWT(k)=i and j=kA(i)B(j)
F W T   x o r FWT\ xor FWT xor : F W T ( k ) = ∑ i   x o r   j = k A ( i ) ∗ B ( j ) FWT(k) = \sum_{i\ xor\ j = k} A(i) * B(j) FWT(k)=i xor j=kA(i)B(j)

you can ignore FWT, because I don’t understand well and in this blog, it will not appear again.

solution

One obvious way to solve this is brute force, whose time complexity is O ( n 4 ) O(n^4) O(n4).

for i = 1 to mask
	for j = 1 to mask
		if i in j
			F[j] += A[i]

It’s obvious that for a mask, we iterate all range is low efficient.
A method to imporve is to iterate the subset of mask.

for i = 1 to mask
	for j = i; j > 0; j = (j - 1) & i
		F[i] += A[j];

Time complexity = ∑ i 2 i   c o n t a i n s   1 = O ( n 3 ) = \sum_{i} 2^{i\ contains\ 1} = O(n^3) =i2i contains 1=O(n3)

sos dp

d p [ m a s k ] [ i ] dp[mask][i] dp[mask][i] present the sum of subsets of mask that the former i i i index has been fixed, and the value of left index can be changed so here the subsets mean the subset of latter.
d p [ m a s k ] [ i ] = { d p [ m a s k ] [ i − 1 ] , ( m a s k   & ( 2 i ) = = 0 ) d p [ m a s k ] [ i − 1 ] + d p [ m a s k ⨁ 2 i ] [ i − 1 ] , ( m a s k   & ( 2 i ) = = 1 ) dp[mask][i] = \left\{\begin{matrix} dp[mask][i - 1],& (mask\ \& (2^i) == 0)\\ dp[mask][i - 1] + dp[mask \bigoplus 2^i][i - 1],& (mask\ \& (2^i) == 1) \end{matrix}\right. dp[mask][i]={dp[mask][i1],dp[mask][i1]+dp[mask2i][i1],(mask &(2i)==0)(mask &(2i)==1)
dp process
code:

for i = 1 to N
	for j = 0 to log(N)
		if (i & (2^j))
			dp[i][j] = dp[i][j - 1] + dp[i - (2^j)][j - 1];
		else
			dp[i][j] = dp[i][j - 1];

d p [ i ] [ − 1 ] = A [ i ] dp[i][-1] = A[i] dp[i][1]=A[i]
The below is dp of i ∈ m a s k i \in mask imask, and the fellow if dp of m a s k ∈ i mask \in i maski.
d p [ m a s k ] [ i ] = { d p [ m a s k ] [ i − 1 ] + d p [ m a s k ⨁ 2 i ] [ i − 1 ] , ( m a s k   & ( 2 i ) = = 0 ) d p [ m a s k ] [ i − 1 ] , ( m a s k   & ( 2 i ) = = 1 ) dp[mask][i] = \left\{\begin{matrix} dp[mask][i - 1] + dp[mask \bigoplus 2^i][i - 1],& (mask\ \& (2^i) == 0)\\ dp[mask][i - 1],& (mask\ \& (2^i) == 1) \end{matrix}\right. dp[mask][i]={dp[mask][i1]+dp[mask2i][i1],dp[mask][i1],(mask &(2i)==0)(mask &(2i)==1)

code:

for i = 1 to N
	for j = 0 to log(N)
		if (i & (2^i))
			dp[i][j] = dp[i][j - 1];
		else
			dp[i][j] = dp[i][j - 1] + dp[i + (2^j)][j - 1];

The difference of o r or or a n d and and can be thought of bits.
When i ∈ m a s k i \in mask imask, the bit 1 of mask can change to 0 or 1, 0 of mask still remain 0, which is equivalent to b i t ( ! i   o r   m a s k ) = 1 bit(!i\ or\ mask) = 1 bit(!i or mask)=1;
When m a s k ∈ i mask \in i maski, the bit 1 of m a s k mask mask still remain 1, 1 of mask can change to 0 or 1, which is equivalent to b i t ( i   o r   ! m a s k ) = 1 bit(i\ or\ !mask) = 1 bit(i or !mask)=1.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值