首页 > 代码库 > [USACO 6.5.1]All Latin Squares
[USACO 6.5.1]All Latin Squares
题解
搜索剪枝.
置换圈个数相同及对应的置换圈内元素个数相同即视为相同方案.
代码
/*TASK:latinLANG:C++*/#include <cstdio>#include <cstring>#include <iostream>using namespace std;int n, s[10][10], fact[] = {1, 1, 2, 6, 24, 120, 720, 5040};bool row[10][10], col[10][10];long long f[10][100];long long dfs(int x, int y){ if (x == n) return 1; int totn = 0, totlen = 1; if (x == 3 && y == 2) { int v[10]; memset(v, true, sizeof(v)); for (int i = 1; i <= n; ++i) if (v[i]) { int len = 0, st = i; totn++; for (;;) { len++; v[st] = false; st = s[2][st]; if (!v[st]) break; } totlen *= len; } if (f[totn][totlen] != -1) return f[totn][totlen]; } long long ans = 0; for (int i = 1; i <= n; ++i) if (row[x][i] && col[y][i]) { row[x][i] = col[y][i] = false; s[x][y] = i; if (y == n) ans += dfs(x + 1, 2); else ans += dfs(x, y + 1); row[x][i] = col[y][i] = true; } if (x == 3 && y == 2) return f[totn][totlen] = ans; else return ans;}int main(){ freopen("latin.in", "r", stdin); freopen("latin.out", "w", stdout); scanf("%d", &n); memset(row, true, sizeof(row)); memset(col, true, sizeof(col)); for (int i = 1; i <= n; ++i) { row[i][i] = false; col[i][i] = false; s[1][i] = s[i][1] = i; } memset(f, -1, sizeof(f)); cout << dfs(2, 2) * fact[n-1] << endl; return 0;}
[USACO 6.5.1]All Latin Squares
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。