NYOJ 110 决斗(区间DP + 黑书例题)

题意:

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;
}
原文地址:https://www.cnblogs.com/kedebug/p/2996616.html