( 其他算法与技巧 )【 线性递推 Berlekamp-Massey算法 】
原理请看:https://www.cnblogs.com/p-b-p-b/p/10844127.html
和 https://blog.csdn.net/qq_39972971/article/details/80725873
算法用处: 求解一个数列的最短线性递推式。一般可以用于猜结论/骗分。
比如:1 2 3 4 5 6 7 8 9 的最短递推式是 { 2,-1 } 即 f ( i )= 2 * f ( i-1 ) + (-1) * f ( i-2 )
数列{1,2,4,9,20,40,90}的递推式即为R5={2,-4,18,-18}。
数列{1,1,3,7,17}的递推式位{2,1}. f ( i )= 2 * f ( i-1 ) + f ( i-2 )
数列{1,2,3,4,5,1,2,3,4,5}的递推式位{0,0,0,0,1}. f ( i )= f( i-5 )
模板:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const double eps = 1e-8;
int fail[maxn],cnt;
double val[maxn], delta[maxn];
vector<double> ans[maxn];
int main()
{
int bst=0;
int n;cin>>n;
for ( int i=1; i<=n; i++ ) cin>>val[i];
for ( int i=1; i<=n; i++ ) {
double tmp = val[i];
for ( int j=0; j<ans[cnt].size(); j++ ) {
tmp -= ans[cnt][j] * val[ i-j-1 ];
}
if ( fabs(tmp)<=eps ) continue ;
delta[cnt] = tmp;
fail[cnt] = i;
cnt++;
if ( cnt==1 ) {
ans[cnt].resize(i);
continue ;
}
double mul = delta[cnt-1]/delta[ bst ];
vector<double> now;
now.resize( i-fail[bst]-1 );
now.push_back(mul);
for ( int j=0; j<ans[bst].size(); j++ ) {
now.push_back( -ans[bst][j] * mul );
}
ans[cnt]=now;
if ( ans[cnt-1].size()>now.size() ) {
ans[cnt].resize( ans[cnt-1].size() );
}
for ( int j=0; j<ans[cnt-1].size(); j++ ) {
ans[cnt][j] += ans[cnt-1][j];
}
if ( i-fail[bst]+ans[bst].size()>ans[cnt-1].size() ) bst=cnt-1;
}
for ( int i=0; i<ans[cnt].size(); i++ ) cout << ans[cnt][i] << " ";
return 0;
}
/*
数列{1,2,4,9,20,40,90}的递推式即为R5={0,0,10,0}。
数列{1,1,3,7,17}的递推式位{2,1}.
*/