半记忆化搜索(空间与时间平衡的艺术)
单论空间,用 a 数组直接记录;计算实践得出总时间复杂度一亿多一点。
具体思路:前面 14 次幂采用暴力枚举: 3^14 ,后面 4 次幂采用记忆化搜索:2^(2^4)
# include <bits/stdc++.h>
using namespace std;
# define ll long long
# define _for ( i, a, b) for ( int i = ( a) ; i <= ( b) ; i ++ )
int n, m;
bool a[ 20 ] [ ( 1 << 20 ) + 9 ] , vis[ ( 1 << 16 ) + 9 ] ;
int f[ ( 1 << 16 ) + 9 ] ;
int dfs ( int x) {
if ( x == 0 ) {
if ( a[ x] [ 1 ] ) return 1 ;
else return 0 ;
}
if ( x == 4 )
{
int p = 0 ;
_for ( i, 1 , 1 << x)
{
p <<= 1 ;
if ( a[ x] [ i] ) p |= 1 ;
}
if ( ! vis[ p] ) {
vis[ p] = true ;
int t = 1 << x - 1 ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] & a[ x] [ ( i << 1 ) - 1 ] ;
f[ p] += dfs ( x - 1 ) ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] | a[ x] [ ( i << 1 ) - 1 ] ;
f[ p] += dfs ( x - 1 ) ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] ^ a[ x] [ ( i << 1 ) - 1 ] ;
f[ p] += dfs ( x - 1 ) ;
}
return f[ p] ;
}
int t = 1 << x - 1 ;
int ans = 0 ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] & a[ x] [ ( i << 1 ) - 1 ] ;
ans += dfs ( x - 1 ) ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] | a[ x] [ ( i << 1 ) - 1 ] ;
ans += dfs ( x - 1 ) ;
_for ( i, 1 , t) a[ x - 1 ] [ i] = a[ x] [ i << 1 ] ^ a[ x] [ ( i << 1 ) - 1 ] ;
return ans + dfs ( x - 1 ) ;
}
int main ( ) {
cin >> n;
string s; cin >> s;
_for ( i, 0 , ( 1 << n) - 1 )
{
if ( s[ i] == '1' ) a[ n] [ i + 1 ] = true ;
else a[ n] [ i + 1 ] = false ;
}
cout << dfs ( n) ;
return 0 ;
}
涉及算法:搜索,记忆化搜索