• BZOJ2729: [HNOI2012]排队


    BZOJ2729: [HNOI2012]排队

    Description

    某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。
    他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)

    Input

    只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。
     
    对于 30%的数据 n≤100,m≤100
     
    对于 100%的数据 n≤2000,m≤2000

    Output

    输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。
    注意答案可能很大。

    Sample Input

    1 1

    Sample Output

    12

    题解Here!

    这个题比较烦人。
    分类讨论一下:

    • 两个老师中间只站着一个女生。

    这时$ ext{两老师+一女生}$应该看做一个整体。
    对应答案就是:
    $$A(n,n) imes A(n+1,1) imes A(2,2) imes A(n+2,m-1)$$

    • 两个老师中间不止站一个女生。

    这时中间一定有男生,于是随便插空就好了。
    对应答案就是:
    $$A(n,n) imes A(n+1,2) imes A(n+3,m)$$
    然后题目中也说了,答案可能很大,所以。。。

    高精度

    还是压了$5$位的高精度。。。

    但是我上次不是立了个$flag$——不再写高精了吗?

    嘿嘿,这次我是直接复制的高精模板哈哈哈!

    不过我以后还是不写高精,只复制模板!

    附代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #define MAXN 10010
    #define L 100000
    using namespace std;
    int n,m;
    struct Bignum{
    	int len;
    	long long val[MAXN];
    	void clean(){
    		len=0;
    		memset(val,0,sizeof(val));
    	}
    	void init(int k){
    		clean();
    		len=1;
    		val[1]=k;
    	}
    	void write(){
    		printf("%lld",val[len]);
    		for(int i=len-1;i>=1;i--)printf("%05lld",val[i]);
    		printf("
    ");
    	}
    	friend Bignum operator +(Bignum x,Bignum y){
    		Bignum s;
    		s.clean();
            s.len=max(x.len,y.len)+12;
            for(int i=1;i<=s.len;i++){
                s.val[i]+=x.val[i]+y.val[i];
                s.val[i+1]+=s.val[i]/L;
                s.val[i]%=L;
            }
    		for(int i=1;i<=s.len;i++){
    			s.val[i+1]+=s.val[i]/L;
    			s.val[i]%=L;
    		}
    		while(s.len&&!s.val[s.len])s.len--;
            return s;
        }
        friend Bignum operator *(Bignum x,Bignum y){
        	Bignum s;
        	s.clean();
        	s.len=x.len+y.len+12;
        	for(int i=1;i<=x.len;i++)
        	for(int j=1;j<=y.len;j++){
        		s.val[i+j-1]+=x.val[i]*y.val[j];
        		s.val[i+j]+=s.val[i+j-1]/L;
        		s.val[i+j-1]%=L;
    		}
    		for(int i=1;i<=s.len;i++){
    			s.val[i+1]+=s.val[i]/L;
    			s.val[i]%=L;
    		}
    		while(s.len&&!s.val[s.len])s.len--;
    		return s;
        }
    }ans;
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    Bignum A(int n,int m){
    	Bignum s,x;
    	s.clean();
    	if(m>n)return s;
    	s.init(1);
    	if(!m)return s;
    	for(int i=n-m+1;i<=n;i++){
    		x.clean();x.init(i);
    		s=s*x;
    	}
    	return s;
    }
    inline void solve(int n,int m){
    	ans=A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*A(n+1,1)*A(2,2)*A(m,1)*A(n+2,m-1);
    	ans.write();
    }
    int main(){
    	n=read();m=read();
    	solve(n,m);
        return 0;
    }
    
  • 相关阅读:
    千亿美元规模,云计算的下半场将走向何方?
    巧用云原生能力和工具,提升云上运维效率
    基础设施代码化(IaC)的自动化配置与编排
    盘点2020 | 阿里云弹性计算年度关键词:快、弹、稳
    整体算力提升40% 芯片级安全防护 | 阿里云发布第七代ECS云服务器
    真正云原生的智能运维体系,阿里云发布ECS自动化运维套件
    安装wireshark
    查看linux的登录日志 centos7
    CentOS查看系统当前登录用户信息的4种方法
    free -m查询内存使用情况,祥解
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9512278.html
Copyright © 2020-2023  润新知