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

Posted sainsist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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

 

以上是关于[2019杭电多校第一场][hdu6578]Blank的主要内容,如果未能解决你的问题,请参考以下文章

[补]2019HDU杭电多校第一场A

[2019杭电多校第一场][hdu6582]Path

2019杭电多校第一场 Operation HDU - 6579

2019杭电多校第一场hdu6581 Vacation

2019 杭电多校第一场

2019杭电多校第一场