BZOJ 4321:queue2

传送门https://www.lydsy.com/JudgeOnline/problem.php?id=4321

题意:给你有n个数从1~n,问有多少种方法可以组成一个序列,使得连续的数不相邻

题解:假设这n个数是从小到大一个一个加入数列中的,那么第n个人只有与第n-1个人在一起才是不合法的,所有我们定义dp状态为dp[i][j][0/1]表示前i个人,相邻的不合法的对数是j,并且第i个人是否与第i-1个人是否相邻的方案数

代码如下:

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
LL read() {
    int x = 0, f = 1; char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-')f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
const double eps = 1e-8;
const int mod =  7777777;
const int maxn = 2e3 + 5;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3f;
LL dp[maxn][maxn][2];
int main() {
    /*
    我们将n个数从小到大一个一个加入队列中,那么第n个人只有与第n-1个人在一起才是不合法的,
    所以我们记录f[i][j][0/1]表示前i个人,相邻的不合法的对数是j,
    第i个人和第i-1个人是否相邻 的方案数。那么转移方程也很容易得出。*/
    int n;
    while(~scanf("%d", &n)) {
        dp[2][1][1] = 2;
        for(int i = 3; i <= n; i++) {
            for(int j = 0; j < i; j++) {
                dp[i][j][0] = ((i - j - 2) * dp[i - 1][j][0] + (j + 1) * dp[i - 1][j + 1][0] + (i - j - 1) * dp[i - 1][j][1] + (j) * dp[i - 1][j + 1][1]) % mod;
                if(j)   dp[i][j][1] = (2 * dp[i - 1][j - 1][0] + dp[i - 1][j][1] + dp[i - 1][j - 1][1]) % mod;
            }
        }
        printf("%lld\n", dp[n][0][0]);
    }
    return 0;
}
View Code

 

posted @ 2019-03-07 17:06  buerdepepeqi  阅读(198)  评论(0编辑  收藏  举报