【刷题】【状态压缩】涂抹果酱
3种状态,所以自己写三进制,and
#include<cstdio> #include<cstdlib> #include<cstring> using namespace std; int n,m,k,mod=1e6; bool my_and(int x,int y) { for(int i=1;i<=m;i++) { if(x%3 == y%3) return true; x/=3,y/=3; } return false; } bool check(int x) { int lst=3; for(int i=1;i<=m;i++) { if(lst==x%3) return true; lst=x%3,x/=3; } return false; } int cnt,st[60],f[2][60]; void prepare() { int mx=3; for(int i=1;i<m;i++) mx*=3; for(int i=0;i<mx;i++) if(check(i)==false) st[++cnt]=i; } int main() { scanf("%d%d",&n,&m); prepare(); scanf("%d",&k); int sta=0,x; for(int i=1;i<=m;i++) scanf("%d",&x),sta=sta*3 + x-1; int pos; for(pos=1;pos<=cnt;pos++) if(st[pos]==sta) break; for(int i=1;i<=n;i++) { int nw=i&1,pre=nw^1; memset(f[nw],0,sizeof(f[nw])); if(i==k) if(i!=1) { for(int j=1;j<=cnt;j++) if(!my_and(sta,st[j])) f[nw][pos]=(f[nw][pos]+f[pre][j])%mod; } else f[nw][pos]=1; else { if(i==1) for(int i=1;i<=cnt;i++) f[nw][i]=1; else for(int j=1;j<cnt;j++) for(int k=j+1;k<=cnt;k++) if(!my_and(st[j],st[k])) f[nw][j]=(f[nw][j]+f[pre][k])%mod,f[nw][k]=(f[nw][k]+f[pre][j])%mod; } } int ans=0,ed=n&1; for(int i=1;i<=cnt;i++) ans=(ans+f[ed][i])%mod; printf("%d\n",ans); return 0; }