bzoj5161 longest sequence shape rising pressure DP (DP sets DP) + playing table

Topic Portal

https://lydsy.com/JudgeOnline/problem.php?id=5161

answer

Recall previous methods required by the LIS Division: Order \ (f [i] \) represents the length of \ (I \) of one of the last minimum of the LIS. It can be found regardless of the current DP to where this thing is always increasing.


LIS on the subject and most can maintain some of this stuff about the state, so we consider this array-like pressure. Because this array do not duplicate each, so you can use \ (01 \) to form pressed into a binary number.

As we state at the time of transfer, not the relationship between the number of new arrivals in the end are a few, only care about the size of this new relationship to the number and the number before, so before we can modify \ (f \) is defined as the last one It is the first of several small number of DP already had numbers.

In this way, a number of newly inserted, you can enumerate its size ranking, then replace it after a number, and the numbers behind all \ (+ 1 \) , this can be achieved by shifting the binary number .

Finally \ (dp [n] [2 ^ n - 1] \) is the answer.


Because of \ (I \) bits when the state just enumerate \ (I ^ 2 \) , so the overall complexity is \ (O (n (2 ^ 0 + 2 ^ 1 + 2 ^ 2 + \ cdots)) = O (n-N2 ^) \) .

But \ (O (n2 ^ n) \) in \ (n \ leq 28 \) in front of pale. How to do it?

\ (n = 28 \) when \ (28 \ times 2 ^ { 28} \) is about \ (7E9 \) about, less than one minute finish. So, you can spend a little time to go out orz other gods (probably \ (2-3min \) ) to make a table.

This question and then you can pass up.


Normal Code

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

#define lowbit(x) ((x) & -(x))

const int N = 28 + 7;
const int M = (1 << 27) + 7;
const int P = 998244353;

int n, S;
int dp[2][M], pcnt[M], suf[N];

inline int smod(int x) { return x >= P ? x - P : x; }
inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
inline int fpow(int x, int y) {
    int ans = 1;
    for (; y; y >>= 1, x = (ll)x * x % P) if (y & 1) ans = (ll)ans * x % P;
    return ans;
}

inline void ycl() {
    S = (1 << (n - 1)) - 1;
    for (int s = 1; s <= S; ++s) pcnt[s] = pcnt[s ^ lowbit(s)] + 1;
}

inline void work() {
    ycl();
    int now = 1, pp = 0;
    dp[now][0] = 1;
    for (int i = 1; i < n; ++i) {
        std::swap(now, pp);
        for (int s = 0; s < (1 << i); ++s) dp[now][s] = 0;
        for (int sss = 0; sss < (1 << (i - 1)); ++sss) {
            int pre = 0, s = sss << 1 | 1;
            for (int j = i; j; --j) suf[j] = (s >> (j - 1)) & 1 ? j : suf[j + 1];
            for (int j = 0; j <= i; ++j) {
                if (j) pre += (s >> (j - 1)) & 1;
                int ss, sta, p = suf[j + 1];
                if (p) ss = s ^ (1 << (p - 1));
                sta = (s & ((1 << j) - 1)) | ((ss & ~((1 << j) - 1)) << 1) | (1 << j);
                sadd(dp[now][sta >> 1], dp[pp][sss]);
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= S; ++i) sadd(ans, (ll)(pcnt[i] + 1) * dp[now][i] % P);
    for (int i = 1; i <= n; ++i) ans = (ll)ans * fpow(i, P - 2) % P;
    printf("%d\n", ans);
}

inline void init() {
    read(n);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Play table Code

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back

template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;}

typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii;

template<typename I> inline void read(I &x) {
    int f = 0, c;
    while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
    x = c & 15;
    while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
    f ? x = -x : 0;
}

#define lowbit(x) ((x) & -(x))

const int N = 28 + 7;
const int M = (1 << 27) + 7;
const int P = 998244353;
const int ans[] = {0, 1, 499122178, 2, 915057326, 540715694, 946945688, 422867403, 451091574, 317868537, 200489273, 976705134, 705376344, 662845575, 331522185, 228644314, 262819964, 686801362, 495111839, 947040129, 414835038, 696340671, 749077581, 301075008, 314644758, 102117126, 819818153, 273498600, 267588741};

int n, S;/*
int dp[2][M], pcnt[M], suf[N];

inline int smod(int x) { return x >= P ? x - P : x; }
inline void sadd(int &x, const int &y) { x += y; x >= P ? x -= P : x; }
inline int fpow(int x, int y) {
    int ans = 1;
    for (; y; y >>= 1, x = (ll)x * x % P) if (y & 1) ans = (ll)ans * x % P;
    return ans;
}

inline void ycl() {
    S = (1 << (n - 1)) - 1;
    for (int s = 1; s <= S; ++s) pcnt[s] = pcnt[s ^ lowbit(s)] + 1;
}

inline void work() {
    ycl();
    int now = 1, pp = 0;
    dp[now][0] = 1;
    for (int i = 1; i < n; ++i) {
        std::swap(now, pp);
        for (int s = 0; s < (1 << i); ++s) dp[now][s] = 0;
        for (int sss = 0; sss < (1 << (i - 1)); ++sss) {
            int pre = 0, s = sss << 1 | 1;
            for (int j = i; j; --j) suf[j] = (s >> (j - 1)) & 1 ? j : suf[j + 1];
            for (int j = 0; j <= i; ++j) {
                if (j) pre += (s >> (j - 1)) & 1;
                int ss, sta, p = suf[j + 1];
                if (p) ss = s ^ (1 << (p - 1));
                sta = (s & ((1 << j) - 1)) | ((ss & ~((1 << j) - 1)) << 1) | (1 << j);
//              dbg("i = %d, s = %d, j = %d, sta = %d, now = %d, pre = %d\n", i, s, j, sta, now, pp);
                sadd(dp[now][sta >> 1], dp[pp][sss]);
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= S; ++i) sadd(ans, (ll)(pcnt[i] + 1) * dp[now][i] % P);
    for (int i = 1; i <= n; ++i) ans = (ll)ans * fpow(i, P - 2) % P;
    printf("%d\n", ans);
}*/

inline void work() {
    printf("%d\n", ans[n]);
}

inline void init() {
    read(n);
}

int main() {
#ifdef hzhkk
    freopen("hkk.in", "r", stdin);
#endif
    init();
    work();
    fclose(stdin), fclose(stdout);
    return 0;
}

Guess you like

Origin www.cnblogs.com/hankeke/p/bzoj5161.html