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