zoukankan      html  css  js  c++  java
  • 排队 题解 组合数学+高精度

    因为实在是写不动了,所以菜鸡颓博客为了信奥发展的伟大未来作出一点小小的贡献

    题目描述

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

    输入格式

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

    输出格式

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

    样例输入

    1 1

    样例输出

       12

    题解:
    这是一道组合数学,应该说是非常明显。
    首先我们需要一个数奥生思路开始要正确。
    我们选择固定男生和老师,然后将女生插空,貌似如果固定女生的式子会非常麻烦。我写到一半果断放弃了
    固定男生时是A(n,n);
    固定老师时分两种情况:
    老师卡在一起,也就是老师一起站在两个男生中间,是A(2,2),这时需要一个女生站在老师中间,总式子变成A(n,n)*(n+1)*A(2,2)*A(n+2,m-1),m-1在上面。
    或者老师没有卡在一起,是A(n+1,2),然后女生插空,总式子变成A(n,n)*A(n+1,2)*A(n+3,m).
    合并式子,最终是n!*(2*m+n*(n+3))*(n+1)*(n+2)!/(n-m+3)!。
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define maxn 100010
     5 using namespace std;
     6 int n,m,a[maxn],b[maxn],c[maxn];
     7 void mult(int a[],int b)
     8 {
     9     int x=0;
    10     for(int i=1;i<=a[0];i++)
    11     {
    12         int tmp=a[i]*b+x;
    13         a[i]=tmp%10;
    14         x=tmp/10;
    15     }
    16     while(x)
    17     {
    18         a[++a[0]]=x%10;
    19         x/=10;
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     scanf("%d%d",&n,&m);a[0]=a[1]=1;
    26     for(int i=1;i<=n;i++) mult(a,i);
    27     mult(a,(2*m+n*(n+3)));
    28     mult(a,n+1);
    29     for(int i=n-m+4;i<=n+2;i++) mult(a,i);
    30     for(int i=a[0];i>0;i--) printf("%d",a[i]);
    31     return 0;
    32 }
    代码
    大概就是这样。
     
  • 相关阅读:
    C++ primer 简读
    C++函数及类方法(待补充)
    C++参数传递-复制和引用
    c++动态分配内存
    C++内存与指针
    c++循环
    C++容器vector及迭代器对象iterator
    c++字符类型一些知识点
    CNN中卷积运算转化成矩阵乘法的实现——img2col+GEMM大矩阵乘法
    046 LeetCode go
  • 原文地址:https://www.cnblogs.com/MouDing/p/11121426.html
Copyright © 2011-2022 走看看