HDU - 6578 Blank
meaning of the title
You give \(\\\\\\\\\\\\\\\\{i}, r_{i}, R {i}, x\{i}\\([lu{{i}, ru{{{\\\\\\\) a different number.Ask how many general plans there are.
thinking
First, we can use \(dp[i][j][k][w]\) to represent the number of scenarios, \(i, j, k, w\) does not refer specifically to a number, but to the last occurrence of four different numbers from small to large \((i < J < K < w)).
So we can derive the \(dp\) equation
\[ dp[i][j][k][w] += dp[i][j][k][w-1]\] \[dp[i][j][w-1][w] += dp[i][j][k][w-1]\] \[dp[i][k][w-1][w] += dp[i][j][k][w-1]\] \[dp[j][k][w-1][w] += dp[i][j][k][w-1]\]
We found that the latter one is only related to \(w-1\), \(100^{4}\) has too much space, so we want to make an optimization by changing the last dimension to a scrolling array of size \(2\)
So now our \(dp\) equation is
\[ dp[i][j][k][now] += dp[i][j][k][pre]\] \[dp[i][j][pre][now] += dp[i][j][k][pre]\] \[dp[i][k][pre][now] += dp[i][j][k][pre]\] \[dp[j][k][pre][now] += dp[i][j][k][pre]\] \[now = (pre+ 1)\%2 = pre \oplus1\]
Consider the restrictions when transferring\(dp\)
AC Code
#include <map> #include <set> #include <list> #include <ctime> #include <cmath> #include <stack> #include <queue> #include <cfloat> #include <string> #include <vector> #include <cstdio> #include <bitset> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define lowbit(x) x & (-x) #define mes(a, b) memset(a, b, sizeof a) #define fi first #define se second #define pii pair<int, int> typedef unsigned long long int ull; typedef long long int ll; const int maxn = 1e2 + 10; const int maxm = 1e5 + 10; const ll mod = 998244353; const ll INF = 1e18 + 100; const int inf = 0x3f3f3f3f; const double pi = acos(-1.0); const double eps = 1e-8; using namespace std; int n, m; int cas, tol, T; ll dp[maxn][maxn][maxn][3]; vector< pair<int,int> > lim[maxn]; int check(int a, int b, int c, int d){ //a < b < c < d for(int i = 0; i < lim[d].size(); i++){ int x = lim[d][i].se; int l = lim[d][i].fi; if(x == 1 && l <= c) return 0; if(x == 2 && (l <= b || l > c)) return 0; if(x == 3 && (l <= a || l > b)) return 0; if(x == 4 && (l > a)) return 0; } return 1; } int main() { scanf("%d", &T); while(T--){ scanf("%d%d", &n, &m); int l, r, x; for(int i = 1; i <= n; i++){ lim[i].clear(); } for(int i = 1; i <= m; i++){ scanf("%d%d%d", &l, &r, &x); lim[r].push_back(make_pair(l, x)); } dp[0][0][0][0] = 1; int now = 1; ll ans = 0; for(int w = 1; w <= n; w++){ for(int k = 0; k <= w;k++){ //Every initialization, memset is said to T, to initialize manually for(int j = 0; j <= k; j++){ for(int i = 0; i <= j; i++){ dp[i][j][k][now] = 0; } } } for(int k = 0; k < w; k++){ for(int j = 0; (!k && j <= k) || j < k; j++){ //(!K&j <=k): When 0 is greater than the last one, it can also be equal to 0 and vice versa less than the last one for(int i = 0; (!j && i <= j) || i < j; i++){ if(!check(i, j, k, w-1)){ //If the restriction is not met, make dp = 0 dp[i][j][k][now^1] = 0; continue; } dp[i][j][k][now] = (dp[i][j][k][now] + dp[i][j][k][now^1])%mod; dp[i][j][w-1][now] = (dp[i][j][w-1][now] + dp[i][j][k][now^1])%mod; dp[i][k][w-1][now] = (dp[i][k][w-1][now] + dp[i][j][k][now^1])%mod; dp[j][k][w-1][now] = (dp[j][k][w-1][now] + dp[i][j][k][now^1])%mod; } } } now ^= 1; } now ^= 1; //Don't miss this side for(int k = 0; k < n;k++){ for(int j = 0; (!k && j <= k) || j < k; j++){ for(int i = 0; (!j && i <= j) || i < j; i++){ if(check(i, j, k, n)) //This side wants to judge if the restrictions are met ans = (ans + dp[i][j][k][now])%mod; } } } printf("%lld\n", ans); } return 0; }