首页 > 其他分享 >预处理组合数

预处理组合数

时间:2023-12-02 16:23:18浏览次数:31  
标签:前缀 组合 查询 ans 递推 预处理

预处理组合数

基本做法

针对大多数仅仅是利用组合数求解问题的题目运用递推法打表,不仅方便,而且可以稳稳地控制复杂度,对于需要多次引用组合数的题目效果极佳:

基于组合数公理性质:

\[C^m_n=C^{n-m}_n \]

推得:

\[C^m_n=C^{m-1}_{n-1}+C^m_{n-1} \]

由这个递推公式就可以熟练的写出组合数代码,但要注意初始化:

\[C^0_0=0 \]

\[C^i_0=C^1_0=C^1_1=1 \]

同时,把表打出来后,我们会发现这就是杨辉三角,这个三角可以解决很多问题,记住打印三角的方法也可以打出组合数。

inline void build()
{
      c[0][0]=1;
      c[1][0]=c[1][1]=1;//如上初始化,绝对绝对不能忘记或错,结合常识。
      for(int i=2;i<=2000;i++)
      {
            c[i][0]=1;
            for(int j=1;j<=2000;j++)
          		c[i][j]=c[i-1][j-1]+c[i-1][j];//递推公式。
      }
}

例题

P2822 [NOIP2016 提高组] 组合数问题

这题还需要再用前缀和来优化查询速度
前缀和可以有效减少查询统计时的复杂度,每一次查询\(O(n)\)降到\(O(1)\)
记住:上加左 减左上 加自己
\(ans[i][j]=ans[i][j-1]+ans[i-1][j]-ans[i-1][j-1]\)

inline void build()
{
  c[0][0]=1;
  c[1][0]=c[1][1]=1;
  for(int i=2;i<=2000;i++)
  {
    c[i][0]=1;
    for(int j=1;j<=i;j++)
    {
      c[i][j]=(c[i-1][j-1]+c[i-1][j])%k;
      ans[i][j]=ans[i-1][j]+ans[i][j-1]-ans[i-1][j-1];//前缀和。
      if(!c[i][j])ans[i][j]++;//如果满足结论,计数加一。
    }
    ans[i][i+1]=ans[i][i];//继承。
  }
}
inline void solve()
{
  t=read(),k=read();
  build();
  while(t--)
  {
    n=read(),m=read();
    if(m>n)printf("%lld\n",ans[n][n]);//如果m>n,ans只会达到n,只需输出ans[n,n]就可以了。
    else printf("%lld\n",ans[n][m]);
  }
}

总结

  1. 需掌握组合数的基本两种求解方法(通项公式,递推公式),根据数据范围选定方法。
  2. 结合数据范围找到优化方法,无论是取模还是自己的玄学优化都尝试一下.(建议取模输出的题,绝对不要乱模!既费时又易错)
  3. 掌握前缀和,利用前缀和对降维的作用。

标签:前缀,组合,查询,ans,递推,预处理
From: https://www.cnblogs.com/kdlyh/p/17871761.html

相关文章

  • XmlRPC入门_基于组合类型的客户端、服务端
    1、客户端#include<stdlib.h>#include<stdio.h>#include<xmlrpc-c/base.h>#include<xmlrpc-c/client.h>#include"config.h"/*informationaboutthisbuildenvironment*/#defineNAME"Xmlrpc-cTestClient"#d......
  • 组合按键移植
    参考gitee移植,key_board:用于单片机中的小巧多功能按键支持;最强功能:支持不限数量、任意按键、任意按键的任意状态之间的随意组合!!!(gitee.com)支持:矩阵键盘单io按键 注:在此没有做矩阵键盘,注意按键的电气属性设置,引脚初始化默认是按键上拉,按下为低电平,要根据实际修改。F103......
  • web前端tips:js继承——寄生组合式继承
    上篇文章给大家分享了js继承中的寄生式继承web前端tips:js继承——寄生式继承今天给大家分享一下js继承中的寄生组合式继承寄生组合式继承寄生组合式继承是一种结合了寄生式继承和组合式继承的方式,它的目标是减少组合式继承中多余的调用父类构造函数的开销。在组合式继承......
  • XmlRPC入门_组合类型操作
    1、数组操作#include<iostream>#include<winsock2.h>#include<windows.h>#include<xmlrpc-c/base.hpp>#include<xmlrpc-c/registry.hpp>#include<xmlrpc-c/server_abyss.hpp>#include<direct.h>#include<stdio.h&......
  • 代码随想训练营第四十四天(Python)| 完全背包、518. 零钱兑换 II 、377. 组合总和 Ⅳ
    [完全背包]有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i]。每件物品都有无限个(也就是可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。1、先遍历物品再遍历背包defall_bag(weight,value,bag_weight):dp=[0]*......
  • 【5.0】Python面向对象之组合
    【一】什么是组合在一个类中以另外一个类的对象作为数据属性,称为类的组合。【二】组合的使用组合与继承都是用来解决代码的重用性问题。不同的是:继承是一种“是”的关系,比如老师是人、学生是人,当类之间有很多相同的之处,应该使用继承;而组合则是一种“有”的关系,比如老......
  • 实验10:组合模式
    本次实验属于模仿型实验,通过本次实验学生将掌握以下内容:1、理解组合模式的动机,掌握该模式的结构;2、能够利用组合模式解决实际问题。 [实验任务一]:组合模式用透明组合模式实现教材中的“文件夹浏览”这个例子。1.文件的执行不需真正实现,只需简单提示即可;2.提交源代码;3.......
  • 将1234数字,组成不重复的3数字组合,并统计组合个数
    total=0forainrange(1,5):forbinrange(1,5):forcinrange(1,5):ifa!=banda!=candb!=c:total=total+1print(a,b,c)print(total) ......
  • 【DFS深度优先算法】全排列、组合总和
    全排列题目描述:给定一个没有重复数字的序列,返回其所有可能的全排列。题目链接:46.全排列输入描述:输入:[1,2,3]输出描述:输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]思路:依次从前往后把所有数字,固定在第0个位置,此时再从前往后把剩余数字依次固定在第1个位置,如此......
  • 数据预处理
    缺失值:比赛提供的数据,发现有些单元格是null或空的缺失太多:例如调查人口信息,发现“年龄”这一项缺失了40%,就直接把该项指标删除最简单处理:均值、众数插补定量数据,例如关于一群人的身高、年龄等数据,用整体的均值来补缺失定性数据,例如关于一群人的性别、文化程度:某些事件调......