cf-1767C-Count Binary Strings(区间dp)

题面 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();
}
posted @ 2022-12-31 12:44  Wint_x19  阅读(124)  评论(0)    收藏  举报