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