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

    传送门

    先考虑如何判断无解,设 $sum[i]$ 表示确定的人中,编号大于 $i$ 的人的人数

    如果 $sum[i]>n-i+1$ 则无解,进一步考虑设 $f[i][j]$ 表示当前确定完编号大于等于 $i$ 的人,除去原本固定的人还有 $j$ 人已经确定

    那么有 $f[i][j]=sum_{k=0}^{j}f[i+1][j-k] cdot C_{j}^{k},j in [0,n-i+1-sum[i]]$

    表示在确定 $j-k$ 人的编号的情况下,再选 $k$ 个人编号为 $i$,乘上组合数是因为每个人都是不同的,我们可以在 $j$ 个人中任意选择 $k$ 个编号为 $i$

    记得组合数每次都要重新算,因为模数不同...

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int 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<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=507;
    int T,n,m,mo,sum[N];
    ll C[N][N],f[N][N];
    inline ll fk(ll x) { return x>=mo ? x-mo : x; }
    int main()
    {
        T=read();
        while(T--)
        {
            memset(f,0,sizeof(f)); int a,b,flag=1;
            memset(sum,0,sizeof(sum));
            n=read(),m=read(),mo=read();
            for(int i=1;i<=m;i++)
            {
                a=read(),b=read();
                sum[b]++;
            }
            for(int i=n;i;i--)
            {
                sum[i]+=sum[i+1];
                if(sum[i]>n-i+1) { flag=0; break; }
            }
            if(!flag) { printf("NO
    "); continue; }
            // f[i][j]+=f[i+1][j-k]*C[j][k]
            for(int i=0;i<=300;i++)
            {
                C[i][0]=1;
                for(int j=1;j<=i;j++)
                    C[i][j]=fk(C[i-1][j]+C[i-1][j-1]);
            }
            f[n+1][0]=1;
            for(int i=n;i>=1;i--)
                for(int j=0;j<=n-i+1-sum[i];j++)
                    for(int k=0;k<=j;k++)
                        f[i][j]=fk(f[i][j]+f[i+1][j-k]*C[j][k]%mo);
            printf("YES %lld
    ",f[1][n-m]);
        }
        return 0;
    }
  • 相关阅读:
    UE4 Abc 批量导入
    UE4源码摘录(424)
    JZ10 矩形覆盖
    JZ27 字符串的排列
    JZ66 机器人的运动范围
    JZ65 矩阵中的路径
    JZ12 数值的整数次方
    JZ37 数字在升序数组中出现的次数
    JZ6 旋转数组的最小数字
    JZ67 剪绳子
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11475534.html
Copyright © 2011-2022 走看看