【区间dp】括号序列再战猪猪侠

来源:互联网 发布:原油软件手机版 编辑:程序博客网 时间:2024/06/01 12:32

ydc的题解是只需要两维状态 = =

可是。。。可是我必须写三维才能AC TAT

all表示区间[L, R]是(A) 还是 AB。。

为了O(1)判断处理一个二维数组的前缀和。。

还有这个鬼要特判 u == v的情况

#include <cstdio>#include <iostream>#include <cstring>using namespace std;int read(){int n = 0, sign = 1; char c = getchar();while(c < '0' || c > '9') {if(c == '-') sign = -1; c = getchar(); }while(c >= '0' && c <= '9') { n = n*10 + c-'0'; c = getchar(); }return n * sign;}const int Mod = 998244353;const int Nmax = 305;int N, M;struct Square{int sum[Nmax][Nmax];inline void make_sum(){for (int i = 1; i <= N; ++i)for (int j = 1; j <= N; ++j)sum[i][j] += sum[i - 1][j];for (int i = 1; i <= N; ++i)for (int j = 1; j <= N; ++j)sum[i][j] += sum[i][j - 1];}inline int get_sum(int x1, int x2, int y1, int y2){int temp = sum[x2][y2] + sum[x1 - 1][y1 - 1];temp -= sum[x1 - 1][y2] + sum[x2][y1 - 1];return temp;}}s;int dp[Nmax][Nmax][2];inline void Add(int &a, int b){a += b;while (a > Mod) a -= Mod;}int dfs(int L, int R, bool all){if(L == R) return all;if(~dp[L][R][all]) return dp[L][R][all];int &ans = dp[L][R][all] = 0;if (all) {if(!s.get_sum(L + 1, R, L, L)) Add(ans, dfs(L + 1, R, 0) + dfs(L + 1, R, 1));} else for (int k = L; k < R; ++k) {if(!s.get_sum(L + 1, k, L, L) && !s.get_sum(L, L, k + 1, R) && !s.get_sum(L + 1, k, k + 1, R)) {//printf("%d %d %d\n", L, k, R);Add(ans, (long long)dfs(L, k, 1) * ( (long long)dfs(k + 1, R, 0) + dfs(k + 1, R, 1) ) % Mod);}}//printf("dp[%d][%d][%d] = %d\n", L, R, all, ans);return ans;}int main(){freopen("brackets.in", "r", stdin);freopen("brackets.out", "w", stdout);for (int T = read(); T --; ){N = read(), M = read();memset(s.sum, 0, sizeof(s.sum));bool flag = 0;while (M --){int u = read(), v = read();s.sum[v][u] = 1; if (u == v) flag = 1; }s.make_sum();memset(dp, -1, sizeof(dp));printf("%d\n", flag ? 0 : (dfs(1, N, 0) + dfs(1, N, 1)) % Mod);}return 0;}


0 0
原创粉丝点击