codevs 1994 排队 排列组合+高精度

/*
数学题0.0
最后答案:A(n,n)*A(n+1,2)*A(n+3,m)+A(n,n)*C(m,1)*A(2,2)*C(n+1,1)*A(n+2,m-1);
简单解释一下
+之前的很显然 先排男生 然后老师插空 然后女生插空 显然符合条件
但仔细一想会发现少算了一部分 就是 老师 女生 老师 的情况
在单独考虑着一种 先选夹在中间的女生(C(m,1)) 然后老师换位置 A(2,2)
然后安排这个(C(n+1,1)) 然后剩下的女生插空
注意不能把  老师 女生 老师  和其他女生看成一样的 因为这个具有特殊性
然后就是高精了 最简单的 连压位都不用
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int n,m,a[1000010],b[1000010],c[1000010],ans[10000010],l1,l2,l;
void get_na()
{
    for(int i=2;i<=n;i++)
      {
          for(int j=1;j<=l1;j++)
            a[j]=a[j]*i;
          for(int j=1;j<=l1;j++)
            if(a[j]>=10)
              {
                a[j+1]+=a[j]/10;
              a[j]=a[j]%10;
            }
        while(a[l1+1])
          {
              l1++;
              a[l1+1]+=a[l1]/10;
              a[l1]=a[l1]%10;
          }
      }
}
void get_nb()
{
    for(int i=1;i<=l1;i++)
      b[i]=a[i];
    l2=l1;
}
void Mul1(int x)
{
    for(int i=1;i<=l1;i++)
            a[i]=a[i]*x;
          for(int i=1;i<=l1;i++)
            if(a[i]>=10)
              {
                a[i+1]+=a[i]/10;
              a[i]=a[i]%10;
            }
        while(a[l1+1])
          {
              l1++;
              a[l1+1]+=a[l1]/10;
              a[l1]=a[l1]%10;
          }
}
void Mul2(int x)
{
    for(int i=1;i<=l2;i++)
            b[i]=b[i]*x;
          for(int i=1;i<=l2;i++)
            if(b[i]>=10)
              {
                b[i+1]+=b[i]/10;
              b[i]=b[i]%10;
            }
        while(b[l2+1])
          {
              l2++;
              b[l2+1]+=b[l2]/10;
              b[l2]=b[l2]%10;
          }
}
void Add()
{
    l=max(l1,l2);
    for(int i=1;i<=l;i++)
      c[i]=a[i]+b[i];
    for(int i=1;i<=l;i++)
      if(c[i]>9)
        {
          c[i+1]++;c[i]=c[i]%10;
        }
    while(c[l+1])l++;
}
int main()
{
    scanf("%d%d",&n,&m);
    a[1]=1;l1=1;
    b[1]=1;l2=1;
    get_na();
    get_nb();
    Mul1(n);
    Mul1(n+1);
    for(int i=n+3;i>=n+3-m+1;i--)
      Mul1(i);
    Mul2(2*m);
    Mul2(n+1);
    for(int i=n+2;i>=n+2-m+1+1;i--)
      Mul2(i);
    Add();
    for(int i=l;i>=1;i--)
      printf("%d",c[i]);
    return 0;
}
时间: 2024-11-05 05:19:10

codevs 1994 排队 排列组合+高精度的相关文章

【noi 2.6_9288】&amp;【hdu 1133】Buy the Ticket(DP / 排列组合 Catalan+高精度)

题意:有m个人有一张50元的纸币,n个人有一张100元的纸币.他们要在一个原始存金为0元的售票处买一张50元的票,问一共有几种方案数. 解法:(学习了他人的推导后~) 1.Catalan数的应用7的变形.(推荐阅读:http://www.cnblogs.com/chenhuan001/p/5157133.html).P.S.不知我之前自己推出的公式“C(n,m)*C(2*m,m)/(m+1)*P(n,n)*P(m,m)”是否是正确的. (1)在不考虑m人和n人本身组内的排列时,总方案数为C(m+

高中数学排列组合

一.特殊元素和特殊位置优先策略 例1.由0,1,2,3,4,5可以组成多少个没有重复数字五位奇数. 解:由于末位和首位有特殊要求,应该优先安排,以免不合要求的元素占了这两个位置. 先排末位共有 然后排首位共有 最后排其它位置共有 由分步计数原理得 二.相邻元素捆绑策略 例2. 7人站成一排 ,其中甲乙相邻且丙丁相邻, 共有多少种不同的排法. 解:可先将甲乙两元素捆绑成整体并看成一个复合元素,同时丙丁也看成一个复合元素,再与其它元素进行排列,同时对相邻元素内部进行自排.由分步计数原理可得共有种不同

[BZOJ1005]Prufer数列+排列组合

一棵树的Prufer数列 每次在剩下的树中找到标号最小的叶子节点(对于无根树而言即是度数为1的节点),删去. 同时将其父节点(即与其相连的唯一点)加入Prufer数列当中. 一个Prufer数列所对应的树 G集合开始为空集 设当前处理到Prufer数列的第i项,找到G集合中未出现且在Prufer[i..n-2]未出现过的标号最小的节点,设其为u. 将u加入集合G中,并将u与Prufer[i]连一条边. 最后将在G集合中仍未出现的两个点之间连一条边(其中必定有一个是n). 来思考一下为何可以还原成

学习排列组合总结

刚看了 一点点排列组合的书,写点总结: 首先最基本的2个 公式(貌似数学选修2-几来着有的,还有个什么二项式定理,就是求(a+b)^n展开后的东东.): 1.排列数 A(n,r)=n*(n-1)*(n-2).......*(n-r+1)=n!/(n-r)!(可以理解为从n个颜色不相同的球里取r个且取的顺序不同就算是不同的方案的方案数),另外A(n,n)=n!,有的地方A用P来表示,习惯问题罢了:证明也比较容易(自己写的,可能和标准的思路不一样,下同.): 对于第一个球,有n种取法:第二个有n-1

ACM~排列组合&amp;&amp;hdu样例

排列组合是数学中的一个分支,在计算机编程方面也有很多的应用,主要有排列公式和组合公式,错排公式.母函数.Catalan Number(卡特兰数)等. 一.有关组合数学的公式 1.排列公式   P(n,r)=n!/r! 2.组合公式   C(n,r)=n!/(r!*(n-r)!)  C(n,r)=C(n-1,r)+C(n-1,r-1) 3.错排公式   d[1]=0;   d[2]=1; d[n]=(n-1)*(d[n-1]+d[n-2]) 4.卡特兰数 前几项:1, 2, 5, 14, 42,

排列组合问题的一些整理

初步:加法原理和乘法原理 概念: 加法原理是分类计数原理,常用于排列组合中,具体是指:做一件事情,完成它有n类方式,第一类方式有M1种方法,第二类方式有M2种方法,--,第n类方式有Mn种方法,那么完成这件事情共有M1+M2+--+Mn种方法. 做一件事,完成它需要分成n个步骤,做第一 步有m1种不同的方法,做第二步有m2种不同的方法,--,做第n步有mn种不同的方法.那么完成这件事共有 N=m1×m2×m3×-×mn 种不同的方法. 这个感觉大家都知道(小学奥数就开始学了吧qwq),感觉没有什

HDU--5396(区间dp+排列组合)

做这道题的时候,想到会不会是dp,然后发现dp可做,但是一直被自己坑到死. 枚举最后合并的那个位置,然后对于加减号的,分成的前后两个部分都有不同的组合方法, (a1+a2........) +  (b1,b2.............)         对于每个a,被加b的个数的阶乘次 ,对于每个b,被加a的个数的阶乘次 减法同理 乘法特殊一点 (a1+a2........) *  (b1,b2.............)  乘法分配率,直接将两部分的总和相乘即可 想到这些还远远没有结束,因为最

排列组合

(常考)错位排列 有N封信和N个信封,每封信都不装在自己信封里的排列种数记作Dn,则 D1=0,D2=1,D3=2,D4=9,D5=44,D6=265 一.相邻问题---捆绑法 不邻问题---插空法 对于某几个元素不相邻的排列问题,可先将其他元素排好,再将不相邻元素在已排好的元素之间及两端空隙中插入即可. [例题1]一张节目表上原有3个节目,如果保持这3个节目的相对顺序不变,再添进去2个新节目,有多少种安排方法? A.20 B.12 C.6 D.4 [答案]A. [解析] 以下内容需要回复才能看

hdu 1799 (循环多少次?)(排列组合公式)

循环多少次? Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3051    Accepted Submission(s): 1117 Problem Description 我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算