[2019杭电多校第一场][hdu6578]Blank

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578

计数问题想到dp不过分吧...

dp[i][j][k][w]为第1-i位置中4个数最后一次出现的位置从大到小排列后为i>=j>=k>=w,但是会MLE,所以把i滚动掉。

但是这里有限制条件,把所有限制条件按右端点用vector存一下,然后处理到第i个位置时,枚举每个状态和限制条件,如果当前状态不满足则归0。

 1 #include <algorithm>
 2 #include<iostream>
 3 #include <cstdio>
 4 #include <vector>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn = 100 + 5;
 9 const int mod = 998244353;
10 int n, m, ans;
11 int dp[2][maxn][maxn][maxn];
12 vector <pair<int, int>> a[maxn];
13 int main() {
14     int pos;
15     cin >> pos;
16     while (pos--) {
17         int ans = 0;
18         scanf("%d %d", &n, &m);
19         for (int i = 1; i <= n; i++)
20             a[i].clear();
21         for (int i = 0; i < m; i++) {
22             int l, r, x;
23             scanf("%d%d%d", &l, &r, &x);
24             a[r].push_back(pair<int, int>(l, x));
25         }
26         dp[0][0][0][0] = 1;
27         int now = 1;
28         for (int i = 1; i <= n; i++, now ^= 1) {
29             for (int j = 0; j <= i; j++)
30                 for (int k = 0; k <= j; k++)
31                     for (int t = 0; t <= k; t++)
32                         dp[now][j][k][t] = 0;
33             for (int j = 0; j < i; j++)
34                 for (int k = 0; k <= j; k++)
35                     for (int t = 0; t <= k; t++) {
36                         dp[now][j][k][t] = (dp[now ^ 1][j][k][t] + dp[now][j][k][t]) % mod;
37                         dp[now][i - 1][k][t] = (dp[now ^ 1][j][k][t] + dp[now][i - 1][k][t]) % mod;
38                         dp[now][i - 1][j][t] = (dp[now ^ 1][j][k][t] + dp[now][i - 1][j][t]) % mod;
39                         dp[now][i - 1][j][k] = (dp[now ^ 1][j][k][t] + dp[now][i - 1][j][k]) % mod;
40                     }
41             for (int j = 0; j < i; j++)
42                 for (int k = 0; k <= j; k++)
43                     for (int t = 0; t <= k; t++)
44                         for (auto tmp : a[i])
45                             if (1 + (j >= tmp.first) + (k >= tmp.first) + (t >= tmp.first) != tmp.second)
46                                 dp[now][j][k][t] = 0;
47         }
48         now = n & 1;
49         for (int i = 0; i < n; i++)
50             for (int j = 0; j <= i; j++)
51                 for (int k = 0; k <= j; k++)
52                     ans = (ans + dp[now][i][j][k]) % mod;
53         printf("%d\n", ans);
54     }
55 
56 }
View Code

猜你喜欢

转载自www.cnblogs.com/sainsist/p/11304699.html