題目要求若出現x,則不能出現2x,3xc++
因此咱們考慮構造一個矩陣spa
\(1\ 2\ 4 \ 8……\)debug
\(3\ 6\ 12\ 24……\)code
\(9\ 18\ 36……\)get
\(……\)it
不難發現,對於一個矩陣,若我選擇了一個數x,則在矩陣內該數的相鄰格子都不能選,題目就被轉化成了玉米田了,能夠用狀壓DP解決class
可是直接作是不對的,好比5就沒有出如今這個序列中原理
因此咱們能夠構造多個矩陣,用乘法原理統計答案便可file
#include<bits/stdc++.h> using namespace std; #define il inline #define re register #define debug printf("Now is Line : %d\n",__LINE__) #define file(a) freopen(#a".in","r",stdin);//freopen(#a".out","w",stdout) #define int long long #define inf 123456789 #define mod 1000000001 il int read() { re int x = 0, f = 1; re char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar(); return x * f; } #define rep(i, s, t) for(re int i = s; i <= t; ++ i) #define drep(i, s, t) for(re int i = t; i >= s; -- i) #define mem(k, p) memset(k, p, sizeof(k)) #define maxn 100005 int n, m, a[20][20], g[1 << 15], vis[maxn], H, L[20], dp[20][1 << 15], ans = 1; il void martix(int x) { H = 0; rep(i, 1, 18) { a[i][1] = (i == 1) ? x : a[i - 1][1] * 2; if(a[i][1] > n) break; ++ H, L[i] = vis[a[i][1]] = 1; rep(j, 2, 11) { a[i][j] = a[i][j - 1] * 3; if(a[i][j] > n) break; L[i] = j, vis[a[i][j]] = 1; } } } il int solve() { rep(i, 0, (1 << L[1]) - 1) dp[1][i] = g[i]; rep(i, 2, H) { rep(j, 0, (1 << L[i]) - 1) { if(!g[j]) continue; dp[i][j] = 0; rep(k, 0, (1 << L[i - 1]) - 1) { if(g[k] && (k & j) == 0) dp[i][j] += dp[i - 1][k]; } } } int t = 0; rep(i, 0, (1 << L[H]) - 1) t = (t + dp[H][i]) % mod; return t; } signed main() { n = read(); rep(i, 0, (1 << 11) - 1) g[i] = !(i & (i << 1)); rep(i, 1, n) if(!vis[i]) martix(i), ans = ans * solve() % mod; printf("%lld", ans); return 0; }