POJ1321 棋盘问题
题意:中文题不多说
思路:本来是开二分图匹配的专题的,结果开错题开了这题- -,然后看了下数据范围,暴力爆过,额,不过没跑到0MS,于是又用状压DP搞了一发搞到0MS了
代码:
暴力:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 10;
int n, k, vis[N];
char str[N];
vector<int> g[N];
int dfs(int u, int sum) {
if (sum == k) return 1;
if (u == n) return 0;
int ans = 0;
for (int i = 0; i < g[u].size(); i++) {
if (vis[g[u][i]]) continue;
vis[g[u][i]] = 1;
ans += dfs(u + 1, sum + 1);
vis[g[u][i]] = 0;
}
ans += dfs(u + 1, sum);
return ans;
}
int main() {
while (~scanf("%d%d", &n, &k)) {
if (n == -1 && k == -1) break;
for (int i = 0; i < n; i++) {
g[i].clear();
scanf("%s", str);
for (int j = 0; j < n; j++) {
if (str[j] == '#')
g[i].push_back(j);
}
}
printf("%d\n", dfs(0, 0));
}
return 0;
}
DP:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N = 10;
int n, K;
char str[N];
vector<int> g[N];
int dp[N][1<<N];
int bitcount(int x) {
return x == 0 ? 0 : bitcount(x>>1) + (x&1);
}
int main() {
while (~scanf("%d%d", &n, &K) && n != -1) {
for (int i = 1; i <= n; i++) {
g[i].clear();
scanf("%s", str);
for (int j = 0; j < n; j++) {
if (str[j] == '#')
g[i].push_back(j);
}
}
dp[0][0] = 1;
int ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < (1<<n); j++) {
dp[i][j] = dp[i - 1][j];
for (int k = 0; k < g[i].size(); k++) {
if (j&(1<<g[i][k])) {
dp[i][j] += dp[i - 1][j^(1<<g[i][k])];
}
}
if (i == n && bitcount(j) == K)
ans += dp[i][j];
}
}
printf("%d\n", ans);
}
return 0;
}