HDU - 6578 Blank DP +Scrolling Array

Posted by sharan on Tue, 30 Jul 2019 20:01:11 +0200

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;
}

Topics: PHP less