蒟蒻样例不过求条
查看原帖
蒟蒻样例不过求条
658787
newtocpp楼主2024/4/15 22:05
#include <bits/stdc++.h>
using namespace std;
const int N = 1 << 10 + 5;
int n, k, init[N], cnt, _1cnt[N], s1, s2;//init单行合法的所有状态     _1cnt[x]x的二进制中1的个数
long long f[11][N][100], ans;//f[x][s][y] 用y个国王,第x行放状态s的放法
inline int get1cnt(int i)
{
	int res = 0;
	while(i)
	{
		res += i & 1;
		i >>= 1;
	}
	return res;
}
void optbin(int i)//倒序输出树,debug用
{
	while(i)
	{
		printf("%d", i & 1);
		i >>= 1;
	}
	printf("\n");
}
inline bool check_singleline(const int &i)
{
	//return !((i & (i >> 1)) || (i & (i << 1)));
	return !(i & ((i >> 1) | (i << 1)));
}
inline bool check(const int &i, const int &j)
{
	//return !((i & j) || ((i << 1) & j) || ((i >> 1) & j));
	return !((j | (j << 1) | (j >> 1)) & i);
}
int main()
{
	scanf("%d %d", &n, &k);
	//for(int x = 0; x <= (1 << n + 1) - 1; x++)
	for(int x = 0; x < (1 << n); x++)
	{
		_1cnt[x] = get1cnt(x);
		//optbin(x);
		if(check_singleline(x)) init[++cnt] = x;
	}
	f[0][0][0] = 1;
	for(int x = 1; x <= n; x++)
	{
		for(int s1_ = 1; s1_ <= cnt; s1_++)
		{
			s1 = init[s1_];
			for(int s2_ = 1; s2_ <= cnt; s2_++)
			{
				s2 = init[s2_];
				/*printf("check{\n");
				optbin(s1);
				optbin(s2);
				printf("} = %d\n", check(s1, s2));*/
				if(check(s1, s2)) for(int y = 0; y <= k; y++) if(y >= _1cnt[s1]) f[x][s1][y] += f[x - 1][s2][y - _1cnt[s1]];//, printf("f[%d][%d][%d] = %d-%d\n", x, s1, y, f[x][s1][y], x == n && y == k);
			}
		}
	}
	for(int x = 1; x <= cnt; x++) ans += f[n][init[x]][k];//, printf("ans+=f[%d][%d][%d] %d=%d\n", n, init[x], k, f[n][init[x]][k], ans);
	printf("%lld", ans);
	return 0;
}

样例输出16

2024/4/15 22:05
加载中...