zoukankan      html  css  js  c++  java
  • [HAOI 2011] Problem C

    [题目链接]

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

    [算法]

              记 s[i] 表示已经确定的m人中编号大于等于i的人数

              考虑dp , 记fi,j表示剩余(n - m)人中编号大于等于i的人已经确定j个人的编号的方案数,则:f[i][j] = sigma(f[i + 1][j - k] * C(j , k))

              时间复杂度 : O(N ^ 3)

    [代码]

           

    #include<bits/stdc++.h>
    using namespace std;
    #define N 310
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    int n , m , M;
    int cnt[N] , C[N][N] , dp[N][N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    
    int main()
    {
            
            int T;
            read(T);
            while (T--)
            {
                    read(n); read(m); read(M);
                    memset(cnt , 0 , sizeof(cnt));
                    memset(C , 0 , sizeof(C));
                    memset(dp , 0 , sizeof(dp));
                    for (int i = 1; i <= m; ++i)
                    {
                            int x , y;
                            read(x); read(y);
                            ++cnt[y];        
                    }        
                    for (int i = n; i >= 1; --i) cnt[i] += cnt[i + 1];
                    bool tag = true;
                    for (int i = 1; i <= n; ++i)
                    {
                            if (cnt[i] > n - i + 1)
                                    tag = false;
                    }
                    if (!tag)
                    {
                            printf("NO
    ");
                            continue;
                    }
                    for (int i = 0; i <= n; ++i)
                    {
                            C[i][0] = 1;
                            for (int j = 1; j <= i; ++j)
                                    C[i][j] = (1LL * C[i - 1][j] + 1LL * C[i - 1][j - 1]) % M;
                    }
                    dp[n + 1][0] = 1;
                    for (int i = n; i >= 1; --i)
                    {
                            for (int j = 0; j <= n - i + 1 - cnt[i]; ++j)
                            {
                                    for (int k = 0; k <= j; ++k)
                                    {
                                            dp[i][j] = (dp[i][j] + 1LL * dp[i + 1][j - k] % M * C[j][k] % M) % M;
                                    }
                            }
                    }
                    printf("YES %d
    " , dp[1][n - m]);
            }
            
            return 0;
        
    }
  • 相关阅读:
    构建自己的yara数据库
    Java反序列化漏洞研究
    我喜欢的资源
    jvm-垃圾收集
    jvm-内存
    java设计模式--行为模式
    java设计模式--结构型模式
    java设计模式--简介
    netty之 -- 手写rpc框架
    netty之---核心源码剖析
  • 原文地址:https://www.cnblogs.com/evenbao/p/10623909.html
Copyright © 2011-2022 走看看