题意:
http://acm.nyist.net/JudgeOnline/problem.php?pid=110
思路:
1. 区间DP的典型:meet[i][j] = true 的条件是中间存在 k 使得 meet[i][k] == true && meet[k][j] == true && i, j 至少有一个能战胜 k;
2. 由于题目是个环,可以破环为直线,比如:0 1 2 0 1 2 ,区间长度扩大了一倍;
#include <iostream>
#include <algorithm>
using namespace std;
int map[510][510], meet[1010][1010];
int main() {
int cases;
scanf("%d", &cases);
while (cases--) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &map[i][j]);
for (int i = 0; i < 2*n; i++)
meet[i][i] = meet[i][i+1] = true;
for (int d = 2; d <= n; d++) {
for (int i = 0, j = i+d; j < 2*n; i++, j++) {
bool flag = false;
for (int k = i + 1; k < j; k++) {
if (meet[i][k] && meet[k][j] && (map[i%n][k%n] || map[j%n][k%n])) {
flag = true; break;
}
}
meet[i][j] = flag;
}
}
int ans = 0;
for (int i = 0; i < n; i++)
if (meet[i][i+n]) ans += 1;
printf("%d\n", ans);
}
return 0;
}