[DP]BZOJ 4321: queue2

来源:互联网 发布:ots软件什么意思 编辑:程序博客网 时间:2024/05/22 12:35

Description

要求一个n排列的方案数,满足:

  • 任意相差为1的元素不相邻。

n只有1000啦。。

Description

OEIS上居然有这个东西。。
考虑DP吧。挺套路的DP。
考虑前i个数,有j个相邻的元素,最后两个数是否相邻[0/1],计为dpi,j,0/1
因为一个元素加进去只会影响比他小1的数。
这样就没有重复啦。。

#include <bits/stdc++.h>using namespace std;const int MOD = 7777777;const int N = 1010;typedef long long ll;inline char get(void) {    static char buf[100000], *S = buf, *T = buf;    if (S == T) {        T = (S = buf) + fread(buf, 1, 100000, stdin);        if (S == T) return EOF;    }    return *S++;}inline void read(int &x) {    static char c; x = 0;    for (c = get(); c < '0' || c > '9'; c = get());    for (; c >= '0' && c <= '9'; c = get()) x = x * 10 + c - '0';}int n, res;int dp[N][N][2];int pre[N], suf[N];inline void Add(int &x, int a) {    x += a; while (x >= MOD) x -= MOD;}inline int Mod(int x) {    Add(x, 0); return x;}int main(void) {    freopen("1.in", "r", stdin);    scanf("%d", &n);    dp[2][1][1] = 2;    for (int i = 3; i <= n; i++) {        for (int j = 0; j < i; j++) {            Add(dp[i][j][0], (ll)dp[i - 1][j + 1][0] * (j + 1) % MOD);            Add(dp[i][j][0], (ll)dp[i - 1][j + 1][1] * j % MOD);            if (i - j >= 2) Add(dp[i][j][0], (ll)dp[i - 1][j][0] * (i - j - 2) % MOD);            Add(dp[i][j][0], (ll)dp[i - 1][j][1] * (i - j - 1) % MOD);            if (j) Add(dp[i][j][1], dp[i - 1][j - 1][0] * 2);            Add(dp[i][j][1], dp[i - 1][j][1]);            if (j) Add(dp[i][j][1], dp[i - 1][j - 1][1]);        }    }    cout << dp[n][0][0] << endl;    return 0;}
原创粉丝点击