zoukankan      html  css  js  c++  java
  • JZOJ 4872.集体照

    ( ext{Problem})

    一年一度的高考结束了,我校要拍集体照。本届毕业生共分 (n) 个班,每个班的人数为 (A_i)。这次拍集体照的要求非常奇怪:所有学生站一排,且相邻两个学生不能同班。现在,安排这次集体照的老师找到了你,想问问你一共有多少种方案。方案数可能很大,最终结果对 (10^9+7) 取模。

    ( ext{Solution})

    考虑 (dp),按班级做,插入人
    (f_{i,j}) 表示做到第 (i) 个班,已经出现 (j) 对相邻
    那么转移就是当前班分 (k) 组,选 (t) 组插到 (j) 个空中,使他们分离

    ( ext{Code})

    #include<cstdio>
    #include<algorithm>
    #define LL long long 
    #define re register
    using namespace std;
    
    const LL P = 1e9 + 7;
    int n, a[55], sum[55];
    LL fac[1505], C[1505][1505], f[55][1505];
    
    inline void ADD(LL &x, LL y)
    {
    	x += y;
    	if (x > P) x -= P;
    }
    
    int main() 
    {
    	freopen("photo.in", "r", stdin);
    	freopen("photo.out", "w", stdout);
    	scanf("%d", &n);
    	for(re int i = 1; i <= n; i++) scanf("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
    	fac[0] = 1;
    	for(re int i = 1; i <= sum[n]; i++) fac[i] = fac[i - 1] * i % P;
    	for(re int i = 0; i <= sum[n]; i++) C[i][0] = 1;
    	for(re int i = 1; i <= sum[n]; i++)
    		for(re int j = 1; j <= i; j++) C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % P;
    	f[1][a[1] - 1] = 1;
    	for(re int i = 2; i <= n; i++)
    		for(re int j = 0; j < sum[i - 1]; j++)
    			for(re int k = 1; k <= a[i]; k++) 
    				for(re int t = 0; t <= k; t++)
    					ADD(f[i][j + a[i] - k - t], f[i - 1][j] * C[a[i] - 1][k - 1] % P * C[j][t] % P * C[sum[i - 1] + 1 - j][k - t] % P);
    	LL ans = f[n][0];
    	for(re int i = 1; i <= n; i++) ans = ans * fac[a[i]] % P;
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    linux系统禁止root用户通过ssh登录及ssh的访问控制
    POJ 3670 , 3671 LIS
    hello world是怎样运行的?
    MFC框架中消失的WinMain()
    [置顶] android LBS的研究与分享(附PPT)
    POJ 3616 DP
    IMP 导入数据报错 OCI-21500 OCI-22275
    误删/tmp导致hadoop无法启停, jsp无法查看的解决方法
    java的文件操作类File
    C#的可空类型与不可空类型
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15127488.html
Copyright © 2011-2022 走看看