传送门:uestc1291
题解
普通DP:
枚举子集/暴力转移:
O
(
2
n
)
O(2^{n})
O(2n),另一个操作
O
(
1
)
O(1)
O(1)
考虑均摊复杂度:
O
(
2
n
2
)
O(2^{\frac{n}{2}})
O(22n)枚举前
n
2
\dfrac n2
2n位的子集,
O
(
2
n
2
)
O(2^{\frac{n}{2}})
O(22n)处理后
n
2
\dfrac n2
2n位的贡献。
代码
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
int n,K;
int f[256][256],ans;
char s[20];
int main()
{
int i,j,x,st;
scanf("%d%d",&n,&K);
for(i=1;i<=n;++i){
x=0;st=1;
scanf("%s",s+1);
for(j=1;j<=K;++j)
if(s[j]=='1')
x|=(1<<(K-j));
for(j=0;j<=255;++j)
if((j&(x>>8))==j)
st=(st+f[j][x&255])%mod;
ans=(ans+st)%mod;
for(j=0;j<=255;++j)
if(((x&255)&j)==(x&255))
f[x>>8][j]=(f[x>>8][j]+st)%mod;
}
printf("%d",ans);
}