zoukankan      html  css  js  c++  java
  • [HNOI2012]排队 组合数

    公式: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)
    分情况讨论推出公式
    前者为无论何时都合法的,后者为先不合法,然后再合法的(两个老师先站在一 起,然后一个女生
    插进来,所以要把这3个人看成一个整体,然后老师可以左右换,所以乘2,女生    就是m选1,然后整体再插入队伍
    最后得到上面的式子
    由于答案较大,所以要写高精
      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define AC 10000
      4 #define R register int
      5 #define D printf("the k is %d
    ",k);
      6 /*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)
      7 分情况讨论推出公式
      8 前者为无论何时都合法的,后者为先不合法,然后再合法的(两个老师先站在一 起,然后一个女生
      9 插进来,所以要把这3个人看成一个整体,然后老师可以左右换,所以乘2,女生    就是m选1,然后整体再插入队伍
     10 最后得到上面的式子
     11 */
     12 int sum2[AC],a[AC],sum1[AC],k,n,m,tot,tot1,tot2,ans[AC];//每次计   算前将memset a,将高精sum*低精k存入a,然后计算完毕后将a导入sum
     13 
     14 void ADD()//加法
     15 {
     16     for(R i=1;i<=max(tot1,tot2);i++)//error!!!注意这里要加到max(tot1,tot2)!!!
     17     {
     18         ans[i+1]=ans[i+1]+(sum1[i]+sum2[i]+ans[i])/10000;
     19         ans[i]=(ans[i]+sum1[i]+sum2[i])%10000;
     20     }
     21     tot=(tot1+tot2)%10000;
     22     while(!ans[tot] && tot>1)--tot;//注意边界!!!
     23 }
     24 
     25 void add1()//乘法1,计算前一部分
     26 {
     27     memset(a,0,sizeof(a));
     28     for(R i=1;i<=tot1;i++)
     29     {
     30         a[i+1]=a[i+1]+(a[i]+sum1[i]*k)/10000;
     31         a[i]=(a[i]+sum1[i]*k)%10000;
     32     }
     33     tot1+=1;//因为n和m最大就是2000,所以最多也就加这么多位了,又因为压了位,,,所以
     34     while(!a[tot1] && tot1>1)--tot1;
     35     if(!a[tot1])memset(sum1,0,sizeof(sum1));//如果女生太多了会导致没有合法情况!!
     36     else    for(R i=1;i<=tot1;i++)   sum1[i]=a[i];//导入sum
     37 }
     38 
     39 void add2()//乘法2,计算后一部分
     40 {
     41     memset(a,0,sizeof(a));
     42     for(R i=1;i<=tot2;i++)
     43     {
     44         a[i+1]=a[i+1]+(a[i]+sum2[i]*k)/10000;
     45         a[i]=(a[i]+sum2[i]*k)%10000;
     46     }
     47     tot2+=1;//因为n和m最大就是2000,所以最多也就加这么多位了,又因为压了位,,,所以
     48     while(!a[tot2] && tot2>1)--tot2;
     49     if(!a[tot2])memset(sum2,0,sizeof(sum2));
     50     else for(R i=1;i<=tot2;i++)  sum2[i]=a[i];//导入sum
     51 }
     52 
     53 void work()
     54 {
     55     sum1[1]=1;//初始值
     56     tot1=1;
     57     for(R i=2;i<=n;i++)//计算A(n,n),即n!
     58     {
     59         k=i;
     60         add1();
     61     }
     62     k=n;
     63     add1();
     64     k=n+1;//分开乘,不然k太大会爆
     65     add1();
     66     k=n+3;
     67     for(R i=1;i<=m;i++)//计算A(n+3,m)
     68     {
     69         add1();
     70         --k;
     71     }
     72     //一二部分分割线~~~~~~~~~~~~~~~
     73     sum2[1]=2*(n+1);//不会破万,所以直接放在第一个即可
     74     tot2=1;
     75     k=m;
     76     add2();
     77     for(R i=2;i<=n;i++)
     78     {
     79         k=i;
     80         add2();
     81     }
     82     k=n+2;
     83     for(R i=1;i<=m-1;i++)
     84     {
     85         add2();
     86         --k;
     87     }
     88     ADD();//最后把sum1和sum2相加得到ans
     89     printf("%d",ans[tot--]);
     90     for(R i=tot;i>=1;i--)printf("%04d",ans[i]);
     91     /*printf("
    ");
     92     while(!sum1[tot1])tot1--;
     93     printf("%d",sum1[tot1]);
     94     for(R i=tot1-1;i>=1;i--)printf("%04d",sum1[i]);*/
     95 }
     96 
     97 int main()
     98 {
     99     freopen("in.in","r",stdin);
    100     scanf("%d%d",&n,&m);
    101     work();
    102     fclose(stdin);
    103     return 0;
    104 }
     
  • 相关阅读:
    火狐浏览器看哪些地方加nofollow
    2017.6.14-网站分析
    2017.6.11-目标关键词优化 三个方面内容
    2017-6-9长尾关键词优化
    2017.6.7seowhy学习笔记---seo知识总纲
    使用 WordPress 自定义字段功能为文章添加下载按钮
    xftp和xshell有什么区别
    决定网站排名的6个干货
    转载:如何在wordpress主题中添加设置页面
    win10+ubuntu双系统安装方案
  • 原文地址:https://www.cnblogs.com/ww3113306/p/8763073.html
Copyright © 2011-2022 走看看