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

    链接 P2523 [HAOI2011]Problem c

    • 想法还是很巧妙的。
    • 其实只是问一个先后顺序,因为编号相同的话,那么(id)小的就在前面,(id)大的就在后面。
    • 所以我们考虑的是到底有哪一些人拿到的是相同的编号。
    • 先考虑无解的情况,也就是如果编号(≥i)的人放不下了。
    • 其他的情况都是有解的。
    • 其实我们不需要关心那一些有人的地方,也就是我们现在可以把已经有人的地方扣出来,把确定的了位置的人也扣除来。
    • 现在问题变成了有(n-m)个人,没有人确定位置的问题了。
    • 考虑(f_{i,j})表示考虑了编号为(i)(n)给谁,已经确定了(j)个人拿到的编号。
    • 那么有$$f_{i,j}=∑f_{i+1,j-k}×C_{j}^{k} (0≤j≤p_i)$$
    • 其中(p_i)表示编号大于(i)可以确定的人数。
    • 这里的含义就是考虑在(j)个人中取出了(k)个人作为编号(i),因为人有编号,所以组合数一下。
    • 答案(f_{n-m,0})
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define R register int
    using namespace std;
    const int N=400;
    int n,m,t,u,v,mod,Q[N],s[N],C[N][N],f[N][N];
    void add(R &x,R y){x=(x+y>=mod?x+y-mod:x+y);}
    void sol(){
        scanf("%d %d %d",&n,&m,&mod);
        memset(f,0,sizeof(f));
        memset(C,0,sizeof(C));
        memset(s,0,sizeof(s));
        for(R i=0;i<=n;++i)C[i][0]=1,s[i]=0;
        for(R i=1;i<=n;++i)
            for(R j=1;j<=i;++j)
                C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        for(R i=n;i>=1;--i)s[i]=s[i+1]+1;
        for(R i=1;i<=m;++i){
            scanf("%d %d",&u,&v);
            for(R j=1;j<=v;++j){
                s[j]--;
                if(s[j]<0){puts("NO");return;}
            }
        }
        f[n+1][0]=1;
        for(R i=n;i>=1;--i)
            for(R j=0;j<=s[i];++j)
                for(R k=0;k<=j;++k)
                    f[i][j]=(f[i][j]+1ll*f[i+1][j-k]*C[j][k]%mod)%mod;
        printf("YES %d
    ",f[1][n-m]);
    }
    int main(){
        cin>>t;
        while(t--)sol();
        return 0;
    }
    
    
  • 相关阅读:
    Andorid中写文件后在电脑上看不到的解决办法
    【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
    OpenCV入门学习笔记
    视频播放(iOS开发)
    音频播放(iOS开发)
    iPad开发(相对于iPhone开发时专有的API)
    静态库/内存分析/通讯录/换肤/硬件信息获取
    Alpha冲刺! Day1
    软工团队
    软工团队
  • 原文地址:https://www.cnblogs.com/Tyher/p/9833520.html
Copyright © 2011-2022 走看看