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。

  • 相关阅读:
    女程序员这么少是因为怕秃头?如果你这样想,那就错了...
    使用简单的c#示例的坚实的架构原则
    第1部分设计模式FAQ(培训)
    为什么微软部分类和Java不?
    现实世界四部分类和部分方法的使用
    回到基础:n层ASP的异常管理设计指南。网络应用
    学习c#(第9天):理解c#中的事件(一种见解)
    EventBroker:同步和异步通知组件,松散耦合的事件处理
    潜水在OOP(第一天):多态和继承(早期绑定/编译时多态)
    学习c#(第8天):c#中的索引器(一种实用方法)
  • 原文地址:https://www.cnblogs.com/qq359084415/p/3371186.html
Copyright © 2011-2022 走看看