• 数学考试【dp】


    题意

    (1 sim n) 的排列,有 (m) 个限制条件,第 (i) 个限制条件 (p_i) 表示前 (p_i) 个数不能是 (1sim p_i) 的排列,求符合要求的排列的个数。答案对 (20000311) 取模。

    链接:https://ac.nowcoder.com/acm/contest/7745/C

    (nleq 2000, m,p_i<n)

    分析

    首先定于状态:(dp[i]) 表示处理到第 (p_i) 个数时,前 (i-1) 个条件满足而第 (i) 个条件不满足的方案数。这个状态定义很重要,方便后面去重。

    那么答案就是:

    [ans=n!-sum_{i=1}^{m}{dp[i] imes (n-p[i])!} ]

    显然,(dp[1]=fac[p[1]])(dp[2]=fac[p[2]]-dp[1]*fac[p[2]-p[1]]),其它的以此类推。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    const int mod=20000311;
    const int N=2010;
    int dp[N],fac[N],p[N];
    void init()
    {
        int maxn=2000;
        fac[0]=1;
        for(int i=1;i<=maxn;i++)
            fac[i]=1LL*fac[i-1]*i%mod;
    }
    int main()
    {
        init();
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
            scanf("%d",&p[i]);
        sort(p+1,p+1+m);
        dp[1]=fac[p[1]];
        for(int i=2;i<=m;i++)
        {
            dp[i]=fac[p[i]];
            for(int j=1;j<i;j++)
                dp[i]=(dp[i]-1LL*dp[j]*fac[p[i]-p[j]]%mod+mod)%mod;
        }
        int ans=fac[n];
        for(int i=1;i<=m;i++)
            ans=(ans-1LL*dp[i]*fac[n-p[i]]%mod+mod)%mod;
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    CSS关键词的值-currentColor关键字提示文字(当前颜色)
    DOM 对象方法
    CSS三种样式表
    html页面不使用缓存的代码
    DOM-----style属性对照表
    UISwitch属性
    UIImageView属性
    UIView属性
    UIScrollView
    UILabel属性
  • 原文地址:https://www.cnblogs.com/1024-xzx/p/13838562.html
Copyright © 2020-2023  润新知