非常巧妙地题目
对于一个数x
列出这样的矩阵
x 2x 4x 8x ……
3x 6x 12x 24x ……
…………………………
不难方案数就是求取数不相邻的方案数
考虑矩阵宽不超过logn,所以可以用状压dp解决
1 const mo=1000000001; 2 3 var f:array[0..18,0..100010] of longint; 4 s:array[0..18] of longint; 5 v:array[0..100010] of boolean; 6 i,n:longint; 7 ans:int64; 8 9 function dp(x:longint):int64; 10 var i,j,k,y:longint; 11 begin 12 dp:=0; 13 y:=x; 14 v[x]:=true; 15 s[1]:=1; 16 while y*3<=n do 17 begin 18 y:=y*3; 19 v[y]:=true; 20 inc(s[1]); 21 end; 22 for j:=0 to 1 shl s[1]-1 do 23 if j and (j shl 1)=0 then f[1,j]:=1; 24 25 i:=1; 26 while x*2<=n do 27 begin 28 inc(i); 29 x:=x*2; 30 y:=x; 31 s[i]:=1; 32 v[y]:=true; 33 while y*3<=n do 34 begin 35 y:=y*3; 36 v[y]:=true; //避免重复 37 inc(s[i]); 38 end; 39 for j:=0 to 1 shl s[i]-1 do 40 f[i,j]:=0; 41 for j:=0 to 1 shl s[i]-1 do 42 if j and (j shl 1)=0 then 43 for k:=0 to 1 shl s[i-1]-1 do 44 if j and k=0 then f[i,j]:=(f[i,j]+f[i-1,k]) mod mo; 45 end; 46 for j:=0 to 1 shl s[i]-1 do 47 inc(dp,f[i,j]); 48 end; 49 50 begin 51 readln(n); 52 ans:=1; 53 for i:=1 to n do 54 if not v[i] then 55 ans:=ans*dp(i) mod mo; //这显然是乘法原理 56 writeln(ans); 57 end.