题面 https://codeforces.com/problemset/problem/1767/C
下面展示带注释的ac代码 在代码里解释思路
Ac代码
#include<bits/stdc++.h>
#define io ios::sync_with_stdio(false);
#define off cin.tie(0), cout.tie(0);
#define int long long
using namespace std;
const int mod = 998244353;
int t = 1, n, m, x, k;
int dp[110][110], arr[110][110];
// dp[i][j]->i之前的第一个断点在j后(i前的最右断点在 j 和 j+1 之间)
void run() {
cin >> n;
for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) cin >> arr[i][j];
if (arr[1][1] != 2) dp[1][0] = 2; // 若合法 则第一位之前没有断点时有 0,1 两种情况
for (int pos = 1; pos <= n; pos++) { // 枚举位置 1~n
for (int gap = 0; gap < pos; gap++) { // 枚举 i之前最后断点 0~pos-1 (断点在0代表i之前没有断点)
int flag = 1;
for (int now = 1; now <= gap; now++) // 枚举从1到断点的所有位置 这段区间出现1的话代表[now,pos]内全相同 即和有断点矛盾
if (arr[now][pos] == 1)
flag = 0;
for (int now = gap + 1; now <= pos; now++) // 枚举从断点到i的所有位置 这段区间出现2的话代表[now,pos]内不是全相同的 即和没有断点矛盾
if (arr[now][pos] == 2)
flag = 0;
if (flag == 0) // 断点在此不成立
dp[pos][gap] = 0;
dp[pos + 1][gap] = dp[pos][gap]; // 即断点不变 pos的增加只会使得后面相同的数字更长 方案数不变
dp[pos + 1][pos] = (dp[pos + 1][pos] + dp[pos][gap]) % mod; // 即确定了pos位与pos-1位不同 问有几种方案
}
}
int ans = 0;
for (int i = 0; i < n; i++) // 枚举所有最后断点的方案数相加
ans = (ans + dp[n][i]) % mod;
cout << ans << '\n';
}
signed main () {
io off
run();
}