zoukankan      html  css  js  c++  java
  • bzoj2302: [HAOI2011]Problem c

    bzoj2302: [HAOI2011]Problem c


    OI题有三种从一般到特殊,从暴力到优化,换角度思考 WerkeyTom_FTD
    这道题让我认识到了从题目到充要条件的转换这种解题思路
    这道题我们可以看出他的充要条件为
    j,ni=1[ai>=j]<=nj+1
    现在我们要求的便为满足这个条件的序列的合法方案数,这个东西就很好dp了
    f[i][j]表示>=i的a有j个的合法方案数,r[i]表示被钦定为a(a=i)的人有多少个
    m[i]表示被钦定为a(a>i)的人有多少个
    f[i][j]=jr[i]k=0f[i+1][k]Cjkr[i]nkm[i]+l[j<=ni+1]

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    
    const int N = 310;
    
    int C[N][N], p[N], n, m, k, a1, a2, P, f[N][N], r[N];
    
    void Solve () {
        memset (f, 0, sizeof f);
        scanf ("%d%d%d", &n, &m, &P);
        memset (C, 0, sizeof C);
        C[0][0] = 1;
        for (int i = 1; i <= 300; ++i) {
            C[i][0] = 1;
            for (int j = 1; j <= i; ++j) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % P;
        }
        for (int i = 1; i <= n; ++i) p[i] = -1, r[i] = 0;
        for (int i = 1; i <= m; ++i) scanf ("%d%d", &a1, &a2), ++r[a2];
        for (int i = n, l = 0; i; --i) {
             l += r[i];
            if (n - i + 1 < l) {
                puts ("NO");
                return ;
            }
        }
        f[n + 1][0] = 1;
        for (int i = n, l = 0; i; --i) {
            for (int j = l; j <= n - i + 1; ++j)
                for (int k = 0; k <= j - r[i]; ++k)
                    f[i][j] = (f[i][j] + 1ll * f[i + 1][k] * C[n - k + l - m][j - k - r[i]] % P) % P;
            l += r[i];
        }
        printf ("YES %d
    ", f[1][n]);
    }
    
    
    int main () {
        int T; scanf ("%d", &T);
        while (T--) Solve ();
        return 0;
    }
    
  • 相关阅读:
    Mybatis与Spring集成
    Mybatis 多对多
    Mybatis表关联多对一
    Mybatis表关联一对多
    Mybatis增删改查(CURD)
    Mybatis接口注解
    MyBatis环境配置及入门
    MyBatis教程
    Spring JDBC StoredProcedure类示例
    Spring JDBC SqlUpdate类示例
  • 原文地址:https://www.cnblogs.com/dcoi-king/p/7491420.html
Copyright © 2011-2022 走看看