欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

牛客/20328/C Bit Compression

程序员文章站 2024-03-12 23:47:44
...

半记忆化搜索(空间与时间平衡的艺术)

单论空间,用 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;
}

涉及算法:搜索,记忆化搜索