洛谷P2523 [HAOI2011]Problem c(计数dp)

题面

luogu

题解

首先,显然一个人实际位置只可能大于或等于编号

先考虑无解的情况

对于编号为\(i\),如果确认的人编号在\([i,n]\)中数量大于区间长度,那么就无解

\(S[i]\)表示确认的人编号在\([i,n]\)中数量

我们只要考虑剩下的\(n - m\)

\(f[i][j]\)表示编号\(>=i\)的,已经确认了\(j\)

那么我们枚举多少人编号为\(i\)

\(f[i][j] = \sum f[i + 1][j - k] * (^j_k)\)

因为交换一些人的编号也是可行方案,所以乘上一个组合数

Code

#include<bits/stdc++.h>

#define LL long long
#define RG register

using namespace std;
template<class T> inline void read(T &x) {
    x = 0; RG char c = getchar(); bool f = 0;
    while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
    while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
    x = f ? -x : x;
    return ;
}
template<class T> inline void write(T x) {
    if (!x) {putchar(48);return ;}
    if (x < 0) x = -x, putchar('-');
    int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
    for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}

const int N = 310;

int n, m, Mod, s[N], f[N][N], C[N][N];
void pls(int &x, int y) {
    x += y;
    if (x >= Mod) x -= Mod;
}
void solve() {
    read(n), read(m), read(Mod);
    for (int i = 0; i <= 300; i++) C[i][0] = C[i][i] = 1;
    for (int i = 2; i <= 300; i++)
        for (int j = 1; j < i; j++)
            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % Mod;
    memset(s, 0, sizeof(s));
    for (int i = 1, x; i <= m; i++) read(x), read(x), s[x]++;
    for (int i = n; i; i--) s[i] += s[i + 1];
    bool flag = 0;
    for (int i = 1; i <= n; i++)
        if (s[i] > n - i + 1) {
            flag = 1;
            break;
        }
    if (flag) {
        puts("NO");
        return ;
    }
    memset(f, 0, sizeof(f));
    f[n + 1][0] = 1;
    for (int i = n; i; i--)
        for (int j = 0; j <= n - i + 1 - s[i]; j++)
            for (int k = 0; k <= j; k++)
                pls(f[i][j], 1ll * f[i + 1][j - k] * C[j][k] % Mod);
    printf("YES %d\n", f[1][n - m]);
    return ;
}

int main() {
    int T;
    read(T);
    while (T--) solve();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zzy2005/p/10549356.html
0条评论
添加一条新回复