P4461 [CQOI2018]九连环 题解?
我好sb啊
本文的除法都是整除(\(important\))
不放题面了
打爆搜, 找规律。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
const int inf = 1000000005;
int n, a[maxn], ans;
map<int, bool> v;
void dfs(int step) {
int s=0;
int sum=0;
for(int i=1;i<=n;++i) sum+=a[i], s|=(a[i]<<i);
if(!sum) {
ans = min(ans,step);
return;
}
if(v.count(s)) return;
v[s]=1;
if(a[1]) {
a[1]=0;
dfs(step+1);
a[1]=1;
}
if(!a[1]) {
a[1]=1;
dfs(step+1);
a[1]=0;
}
for(int i=1;i<n;++i) if(a[i]) {
if(a[i+1]) {
a[i+1]=0;
dfs(step+1);
a[i+1]=1;
}
if(!a[i+1]) {
a[i+1]=1;
dfs(step+1);
a[i+1]=0;
}
break;
}
}
int main()
{
for(n=1;n<=10;++n) {
v.clear();
for(int i=1;i<=n;++i) a[i]=1;
ans = inf;
dfs(0);
cout<<ans<<'\n';
}
return 0;
}
打出的表
1
2
5
10
21
42
85
170
341
682
递推式是
\[f[i]=
\begin{cases}
0, \quad i=0\\
2*f[i-1]+1, \quad i\&1 \\
2*f[i-1], \quad !(i\&1)
\end{cases}
\]
然后就可以 \(O(n)\) 递推, 不过没模数,显然会炸, 能想到的解决方案就是高精, 而且在这个数据范围下似乎肯定是 \(FFT\) 优化高精快速幂。
可是这个式子很哲学qwq
化简下
\[f[i]=
\begin{cases}
0, \quad i=0\\
f[i-1]+f[i-1]+1, \quad i\&1 \\
f[i-1]+f[i-1], \quad !(i\&1)
\end{cases}
\]
继续拆
\[\begin{cases}
0, \quad i=0\\
1,\quad i=1\\
f[i-1]+2*f[i-2]+1, \quad i\&1 \\
f[i-1]+2*f[i-2]+1, \quad !(i\&1)
\end{cases}
\]
对于最后这个式子可以求它的封闭形式(我不会啊gan, 具体数学&高中数学 没学好qwq)
\[别人的推导!
\]
\[f_n = f_{n-1} + 2*f_{n-2} + 1
\]
\[f_n + f_{n-1}= 2*f_{n-1} + 2*f_{n-2} + 1
\]
\[f_n + f_{n-1} + 1 = 2*f_{n-1} + 2*f_{n-2} + 2
\]
\[= 2*(f_{n-1} + f_{n-2} + 1)
\]
设 \(G_n = f_n + f_{n-1} + 1\), 则
\[G[n]=2^n
\]
将 \(G\) 代入 \(f_n = f_{n-1} + 2*f_{n-2} + 1\), 得
\[f_i = f_{n-1} + 2*f_{n-2} + 1
\]
\[= f_{n-2} + G_{n-1}
\]
\[= f_{n-2} + 2^{n-1}
\]
可以看出,
\(n\) 为奇数时,
\[f_n = 1 + 4 + \cdots 2^{n-3} + 2^{n-1}
\]
\(i\) 为偶数时,
\[f_n = 2 + 8 + \cdots 2^{n-3} + 2^{n-1}
\]
套下等比数列求和公式
\(n\) 为奇数时,
\[f_n = 1*\sum_{i=0}^{\frac{n}2}4^i
\]
\[=\frac{4^{\frac{n}2+1}-1}3
\]
\(n\) 为偶数时,
\[f_n = 2*\sum_{i=0}^{\frac{n}2-1} 4^i
\]
\[= \frac{2^{n+1}-2}3
\]
(扰动法真好用qwq)
然后就可以上 \(FFT\) 快速幂做这道题了qwq。
(当然我也是闲的没事才会干这种事情)
我不想写高精除和高精减qwq