其他分享
首页 > 其他分享> > P1896 互不侵犯(状压dp入门题)

P1896 互不侵犯(状压dp入门题)

作者:互联网

typedef long long ll;
ll dp[10][1 << 10][100];//dp[row][sta][cnt]
int n, k, cnt;
int num[1 << 10];//存状态中1的数量
int tot[1 << 10];//存所有的可行状态

inline int lowbit(int x) {
	return (x & (-x));
}

int main() {
	scanf("%d %d", &n, &k);
	int up = n * n;
	int limit = (1 << n);

	for (int i = 1; i < limit; ++i) {//预处理出每种状态有几个1
		num[i] = num[i - lowbit(i)] + 1;
	}
	
	for (int i = 0; i < limit; ++i) {
		if( ((i & (i >> 1)) == 0) )	tot[cnt ++] = i;
	}

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < cnt; ++j) {
			if (i == 0)	dp[i][tot[j]][num[tot[j]]] ++;
			else {
				for (int k = 0; k < cnt; ++k) {
					if ( (tot[j] & tot[k]) || ((tot[k] >> 1) & tot[j]) || ((tot[k] << 1) & tot[j]) )	continue;
					for (int z = 0; num[tot[j]] + z <= up; ++z) {
						dp[i][tot[j]][num[tot[j]] + z] += dp[i - 1][tot[k]][z];//状态转移
					}
				}
			}
		}
	}

	ll ans = 0;
	for (int i = 0; i < cnt; ++i) {
		ans += dp[n - 1][tot[i]][k];
	}
	printf("%lld\n", ans);
}


标签:cnt,P1896,++,ll,状压,tot,int,dp
来源: https://www.cnblogs.com/wanshe-li/p/13757301.html