状态转移方程
(1). dp[i][j] = true; if dp[i][k]&&dp[j][k]&&(g[i][k]||g[j][k])
(2). dp[i][j] = false;
边界条件
dp[i][j] = false if i >= j
dp[i][j] = true if i + 1 = j
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define INF (int)(1e9)
#define MAXN 8
using namespace std;
int e[45][45], dp[90][90], n;
bool solve(int i, int j) {
if (dp[i][j] != -1) return dp[i][j];
if (i == j || i > j) return dp[i][j] = false;
if (i + 1 == j) return dp[i][j] = true;
dp[i][j] = false;
for (int k = i + 1; k < j; ++ k) {
if (solve(i,k) && solve(k,j)) {
int x1 = i%n;
int x2 = k%n;
int x3 = j%n;
if (e[x1][x2] || e[x3][x2]) dp[i][j] = true;
}
}
return dp[i][j];
}
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif // LOCAL
int t;
cin >> t;
while (t --) {
cin >> n;
memset(dp, -1, sizeof(dp));
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
cin >> e[i][j];
}
}
solve(0, 2*n-1);
for (int i = 0; i < n; ++ i) {
if (dp[i][i+n]) cout << 1 << endl;
else cout << 0 << endl;
}
puts("");
}
}