非常巧妙地题目
对于一个数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.
View Code

 

posted on 2015-01-01 20:58  acphile  阅读(158)  评论(0编辑  收藏  举报