把大视野的老爷机卡了10分钟。。。只是发现数组开小了,然后一手贱又开的很大。。。
这题思路很妙啊。
就是写出很多矩阵,对于一个位置的值x,右边的是3x,下边是2x,然后相邻的不能同取。%这dalao题解吧
然后状压DP(我能说一开始算错复杂度一脸蒙蔽)
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=1000000001; int n; bool v[1100000]; int len[1100]; LL f[20][210000]; int solve(int x) { memset(len,0,sizeof(len)); int zzz=x,L=0; for(int i=1;zzz<=n;i++) { int zgx=zzz; for(int j=1;zgx<=n;j++) { v[zgx]=true; zgx*=2; len[i]=j; } zzz*=3; L=i; } //make the matrix len[0]=1; for(int i=0;i<=L;i++) for(int j=0;j<(1<<len[i]);j++)f[i][j]=0; len[L+1]=0,f[L+1][0]=0; f[0][0]=1; //init for(int i=0;i<=L;i++) { for(int j=0;j<(1<<len[i]);j++) { if(f[i][j]!=0) { if((j&(j>>1))>0)continue; for(int k=0;k<(1<<len[i+1]);k++) { if((j&k)>0)continue; f[i+1][k]=(f[i+1][k]+f[i][j])%mod; } } } } return f[L+1][0]; } int main() { scanf("%d",&n); memset(v,false,sizeof(v)); LL ans=1; for(int i=1;i<=n;i++) if(v[i]==false)ans=(ans*solve(i))%mod; printf("%lld ",ans); return 0; }