zoukankan      html  css  js  c++  java
  • NOIP 2011 提高组 计算系数(vijos 1739)(方法:二项式定理)

         <————————————————————————————————————————————————————————>

                附:   题目链接                vijos 1739                                              地址:https://www.vijos.org/p/1739

         <————————————————————————————————————————————————————————>

                PS:本题关键是二次项定理:(a+b)^n = \sum_{k=0}^n {n \choose k}  a^{n-k}b^k,其中,{n \choose k}=\frac{n!}{k!(n-k)!} 又有\rm
{C}^k_n(即组合数)等记法。

                由二次项定理推结果:

                 c = ax; d = by;    原式 变为 ( c + d ) k

                 则   cn     *  dm      的系数 为  C(k,m)

                 —> anxn  *  bmym 的系数 为  C(k , m)

                —> xn ym             的系数 为  an  *  bm  *  C(k , m)

                求 C(k , m) 成为了结题关键,按照常规算法, C(k , m) = m! / ( k! * (m-k)! )

                 但    很显然 直接累乘 会爆范围              ( 过程中不能mod,因为还要约分母)

                 所以 这题最好用 组合 的递推算法:   C(n , m) = C(n-1 , m) + C(n-1 , m-1)

                 该题解采用 滚动数组 以节省空间。         (值得一提的是 k<=1000 , m<=k)

         <————————————————————————————————————————————————————————>

                 const mo=10007;                        //要求的取mod

                 var
                 c:array[0..1,0..1000] of longint;    //滚动数组 求 组合
                 a,b,k,n,m,i,j,new,old:longint;         //new为 当前决策点,old 为上一决策点

                 begin
                   readln(a,b,k,n,m);
                   a := a mod mo;
                   b := b mod mo;                        //值得一提的是,a、b没mod后几个数据会爆longint,如vijos上不加只能有80 - =
                   c[0,0] := 1;
                   c[1,0] := 1;

         <————————————————————————————————————————————————————————>

                                                 读入数据,并对a,b进行处理,当然也可不处理,采用int64

         <————————————————————————————————————————————————————————>

                 for i := 1 to k do begin
                   new:=1-new;
                   old:=1-new;
                   for j := 1 to m do if i >= j then                     //记得加 i>=j  0 0,否则组合会求错 -  =
                   c[new,j] := (c[old,j-1] + c[old,j]) mod mo;
                 end;

         <————————————————————————————————————————————————————————>

                                                    滚动数组求组合,过程中不边算边mod也会爆范围 - =

         <————————————————————————————————————————————————————————>

                  j := c[new,m];
                  for i := 1 to n do j := (j * a) mod mo;
                  for i := 1 to m do j := (j * b) mod mo;
                  writeln(j);

         <————————————————————————————————————————————————————————>

                                                乘a^n,b^m,得最后结果,同样边乘边mod,理由同上

         <————————————————————————————————————————————————————————>

    end.

         <————————————————————————————————————————————————————————>

                                                                                                                                                          End。

  • 相关阅读:
    十大排序算法
    SQL优化指南
    Python基础-类与对象
    Python基础-函数
    Python基础-字典
    Python基础-字符串
    Python基础-列表
    以太坊智能合约开发框架Truffle
    比特币钱包搭建与使用
    矩阵的压缩存储
  • 原文地址:https://www.cnblogs.com/qq359084415/p/3371186.html
Copyright © 2011-2022 走看看