• HDU


    Blank

    dp[ o ][ i ][ j ][ k ]

    表示前 o 个已经填完, 不同数字的最后一个分别在o, i, j, k, 直接dp, 把限制丢到R, 在R转移出去的时候把不合法的丢掉。

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 100 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 998244353;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    int n, m;
    int dp[2][N][N][N];
    int (*f)[N][N] = dp[0];
    int (*g)[N][N] = dp[1];
    int T;
    vector<PII> V[N];
    
    void init(int n) {
        for(int i = 0; i < n; i++) {
            for(int j = 0; j <= i; j++) {
                for(int k = 0; k <= j; k++) {
                    f[i][j][k] = 0;
                }
            }
        }
    }
    
    int main() {
        scanf("%d", &T);
        while(T--) {
            scanf("%d%d", &n, &m);
            for(int i = 1; i <= n; i++) {
                V[i].clear();
            }
            for(int i = 1; i <= m; i++) {
                int l, r, x;
                scanf("%d%d%d", &l, &r, &x);
                V[r].push_back(mk(l, x));
            }
            init(1);
            f[0][0][0] = 4;
            bool judge;
            for(int o = 1; o < n; o++) {
                swap(f, g);
                init(o + 1);
                for(int i = 0; i < o; i++) {
                    for(int j = 0; j <= i; j++) {
                        for(int k = 0; k <= j; k++) {
                            if(!g[i][j][k]) continue;
                            judge = true;
                            for(auto &t : V[o]) {
                                if(t.se == 1) {
                                    if(i >= t.fi) {
                                        judge = false;
                                        break;
                                    }
                                }
                                else if(t.se == 2) {
                                    if(i < t.fi || j >= t.fi) {
                                        judge = false;
                                        break;
                                    }
                                }
                                else if(t.se == 3) {
                                    if(j < t.fi || k >= t.fi) {
                                        judge = false;
                                        break;
                                    }
                                } else {
                                    if(k < t.fi) {
                                        judge = false;
                                        break;
                                    }
                                }
                            }
                            if(judge) {
                                add(f[i][j][k], g[i][j][k]);
                                add(f[o][i][j], g[i][j][k]);
                                add(f[o][i][k], g[i][j][k]);
                                add(f[o][j][k], g[i][j][k]);
                            }
                        }
                    }
                }
            }
    
            int ans = 0;
            for(int i = 0; i < n; i++) {
                for(int j = 0; j <= i; j++) {
                    for(int k = 0; k <= j; k++) {
                        if(!dp[i][j][k]) continue;
                        judge = true;
                        for(auto &t : V[n]) {
                            if(t.se == 1) {
                                if(i >= t.fi) {
                                    judge = false;
                                    break;
                                }
                            }
                            else if(t.se == 2) {
                                if(i < t.fi || j >= t.fi) {
                                    judge = false;
                                    break;
                                }
                            }
                            else if(t.se == 3) {
                                if(j < t.fi || k >= t.fi) {
                                    judge = false;
                                    break;
                                }
                            } else {
                                if(k < t.fi) {
                                    judge = false;
                                    break;
                                }
                            }
                        }
                        if(judge) {
                            add(ans, f[i][j][k]);
                        }
                    }
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    网络流24题(03)最小路径覆盖问题(二分图匹配 + 最大流)
    POJ 1161 Help Jimmy(逆向思维的DP + 记忆化搜索总结)
    UVa 11248 Frequency Hopping(最小割入门)
    HDOJ 2767 Proving Equivalences(强连通算法入门)
    POJ 1336 The KLeague(最大流)
    POJ 1459 Power Network(最大流入门)
    ZOJ 1679 Telescope(区间DP变型题)
    网络流24题(02)太空飞行计划(最大流最小割)
    POJ 1160 Post Office(抽象的二维DP)
    网络流24题(01)搭配飞行员(最大流)
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11231245.html
Copyright © 2020-2023  润新知