《编程思维与实践》1067.小型组合数

news2025/1/23 6:18:22

《编程思维与实践》1067.小型组合数

题目

在这里插入图片描述

思路

法一:

注意到题目数据最大为 C 40 20 = 137846528820 C_{40}^{20}=137846528820 C4020=137846528820在long long的范围内,所以其实可以不用大整数的处理方法去计算:

由于 C m n = m ! n ! ( m − n ) ! = m ( m − 1 ) . . . ( m − ( n − 1 ) ) n ( n − 1 ) . . . 2 ⋅ 1 C_m^n=\frac{m!}{n!(m-n)!}=\frac{m(m-1)...(m-(n-1))}{n(n-1)...2\cdot 1} Cmn=n!(mn)!m!=n(n1)...21m(m1)...(m(n1)) , 注意到 1 ∣ m , 2 ∣ m ( m − 1 ) , 3 ∣ m ( m − 1 ) ( m − 2 ) … 1|m,2|m(m-1),3|m(m-1)(m-2)… 1∣m,2∣m(m1),3∣m(m1)(m2)

这是因为连续出现的n个数字的乘积必然会存在因子n(可用归纳法证明).

所以只需要将结果依次乘m(m-1)…(m-(n-1))的每一位,然后依次除去因子1,2,3….n即可.

注意的点:

中间步骤可能数据会超过long long的范围, 应该用unsigned long long去存.

法二:

用大整数的处理方式去计算,但需要运用组合数的递推公式 C m n = C m − 1 n + C m − 1 n − 1 C_m^n=C_{m-1}^{n}+C_{m-1}^{n-1} Cmn=Cm1n+Cm1n1 ;

记dp[n][m]=dp[n][m-1]+dp[n-1][m-1],

初始化dp[0][m]=1,dp[m][0]=0,

之后先遍历n(从1到40)再遍历m(从1到40).

代码

法一:

#include<stdio.h>

int main()
{
	int T;
	scanf("%d",&T);
	for(int t=0;t<T;t++)
	{
		int m,n;
		scanf("%d %d",&m,&n);
		unsigned long long ans=1;
		for(int j=0;j<n;j++)
		{
			ans*=m-j;
			ans/=j+1;
		}
		printf("case #%d:\n",t);
		printf("%llu\n",ans);
	}
	return 0;
} 

法二:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 100 
#define L 40     // dp[40][40]

typedef struct{int cnt,v[N];}BIGINT;

BIGINT carry(BIGINT S,int n);   //进位 n表示进制 
BIGINT int2BIG(int x,int bin);  //int 转换(to)成BIGINT 
BIGINT add(BIGINT S, BIGINT T);     //两个大整数相加

int main()
{
	int T;
	scanf("%d",&T);
	BIGINT dp[L+1][L+1];
	for(int i=0;i<L+1;i++)
	{
		for(int j=0;j<L+1;j++)
		{
			dp[i][j]=int2BIG(0,10);
		} 
	}
	for(int j=0;j<L+1;j++)
	{
		dp[0][j]=int2BIG(1,10);	
	}
	for(int i=1;i<L+1;i++)
	{
		for(int j=1;j<L+1;j++)
		{
			dp[i][j]=add(dp[i][j-1],dp[i-1][j-1]);
		}
	}
	for(int t=0;t<T;t++)
	{
		int m,n;
		scanf("%d%d",&m,&n);
		printf("case #%d:\n",t);
		for(int i=dp[n][m].cnt-1;i>=0;i--)  //逆向输出
		{
			printf("%d",dp[n][m].v[i]);
		}
		printf("\n");
	}
    return 0;
}

BIGINT carry(BIGINT S,int n)   //进位 n表示进制 
{
	int flag=0;
	for(int i=0;i<S.cnt;i++)
	{
		int temp=S.v[i]+flag;
		S.v[i]=temp%n;
		flag=temp/n;
	}
    if(flag)   //为了加法进行的方便 可能多一位
    {
        S.v[S.cnt++]=flag;
    }
	return S;
}

BIGINT int2BIG(int x,int bin)  //int 转换(to)成BIGINT 
{
    BIGINT R={0,{0}};
	do
	{
	    R.v[R.cnt++]=x%bin;
	    x/=bin;
	}while(x>0);
	return R;
}

BIGINT add(BIGINT S, BIGINT T)     //两个大整数相加
{
	int max=S.cnt>T.cnt?S.cnt:T.cnt;
	BIGINT R={max,{0}};
	for(int i=0;i<max;i++)
	{
		R.v[i]=S.v[i]+T.v[i];   //依次进行普通乘法
	}
	R=carry(R,10);
	return R;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/521941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql数据库的库操作 --2

目录 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.2&#xff1a;字符集和效验规则 2.3&#xff1a;修改和删除数据库 2.4&#xff1a;数据库的备份和恢复 2.5&#xff1a;查看连接情况 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.1.1&#xff1a;数据库…

AcWing算法提高课-1.3.9庆功会

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 为了庆贺班级在校运动会上取得全校第一名成绩&#xff0c;班主任决定开一场庆功会&#xff0c;为此拨款购买奖品犒劳运动员。 期望…

[golang gin框架] 32.Gin 商城项目- 支付宝支付操作相关功能讲解

一.支付宝支付之前的准备工作 创建应用、配置签名、提交审核 支付宝支付之前的准备工作 支付宝开放平台支持使用 普通公钥、公钥证书 两种签名方式 公钥证书模式下完成支付需要获取的内容&#xff1a; appId 应用私钥 应用公钥证书 支付宝根证书 支付宝公钥证书 普通公钥模式下…

热乎的面经——不屈不挠

⭐️前言⭐️ &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &#x1f349;博客中涉及源码及博主日常练习代码均已上传GitHub &#x1f4…

【Linux常见指令以及权限理解】基本指令(3)

写在前面 上一篇文章&#xff0c;我们学习了Linux的一些常用指令&#xff0c; 学习了如何理解Linux系统&#xff0c;介绍了对Linux系统的理解&#xff1a;Linux下一切皆文件 介绍了重定向还有管道相关的知识。这里是上一篇博客的链接&#xff1a;http://t.csdn.cn/2d6fc 接…

Kali HTTrack演示-渗透测试察打一体(1)

HTTrack是一个免费并易于使用的线下浏览器工具,全称是HTTrack Website Copier for Windows,它能够让你从互联网上下载指定的网站进行线下浏览(离线浏览),也可以用来收集信息(甚至有网站使用隐藏的密码文件),一些仿真度极高的伪网站(为了骗取用户密码),也是使用类似工具做…

[一篇读懂]C语言十二讲:栈与队列和真题实战

[一篇读懂]C语言十二讲&#xff1a;栈与队列和真题实战 1. 与408关联解析及本节内容介绍1 与408关联解析2 本节内容介绍 2. 栈(stack)的原理解析2.1 **栈&#xff1a;只允许在一端进行插入或删除操作的线性表**2.2 栈的基本操作2.3 栈的顺序存储2.4 栈的链表存储 3. 初始化栈 -…

PE文件+UPX壳 ida分析

die查壳发现是UPX壳&#xff0c;直接用ida分析&#xff0c;会发现能分析出来的信息特别少&#xff0c;需要脱壳 工具链接发布 UPX/UPX (github.com) 下载压缩包后解压&#xff0c;直接在该文件路径下cmd&#xff0c;输入upx.exe -h安装完成&#xff0c;使用命令“upx -d 文件路…

计算机网络-网络层与链路层协议分析实验

一.实验目的 通过本实验&#xff0c;进一步熟悉PacketTracer的使用&#xff0c;学习路由器与交换机的基本配置&#xff0c;加深对网络层与链路层协议的理解。 二.实验内容 1.完成路由器交换机的基本配置 2.了解 ICMP 数据包的格式 3.检查ARP交换 三.实验过程 1.完成路由…

链表——循环链表

其他形式的链表——循环链表 循环链表 定义&#xff1a;循环链表是表中最后一个结点的指针指向头结点&#xff0c;使链表构成环状 特点&#xff1a;从表中任一结点发出均可找到表中其他结点&#xff0c;提高查找效率 双向循环链表 data&#xff1a;数据元素 prior&#xff1…

进程间通信--管道

文章目录 一.通信二.管道匿名管道&#xff08;只能用于有血缘关系的进程之间通信&#xff09;1.匿名管道的创建2.匿名管道的读取情况3.管道的特征4.基于匿名管道的简单进程池 有名管道&#xff08;用于没有血缘关系的进程间的通信&#xff09;1.有名管道的建立和删除2.通过一段…

CodeForces 438 D线段树暴力修改

线段树暴力修改 关键是每个数取余操作&#xff0c;看似我们如果暴力改的话m*n肯定超时了 容易发现一个数小于给定模数的时候&#xff0c;取模不会发生改变&#xff0c;而大于给定模数的时候我们得到的最大的结果是x/2向上取整&#xff0c;结果一定小于等于这个数字,这里我想说…

AECC全球留学趋势报告解读

AECC全球留学趋势报告解读 相对更安全的留学目的地&#xff1a; 留学安全是留学生及家长最关注的一个问题。报告显示&#xff0c;在“你认为相对更安全的留学目 的"的问答中&#xff0c;澳大利亚获得总评8.76分&#xff08;满分10分&#xff09;位居第一。 英澳新留学更受…

VMware Tanzu Kubernetes Grid (TKG) 2.1 - 企业级 Kubernetes 解决方案

VMware Tanzu Kubernetes Grid (TKG) 2.1 - 企业级 Kubernetes 解决方案 VMware 构建、签名和支持的开源 Kubernetes 容器编排平台的完整分发版 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-tkg-2/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

华为OD机试真题 Java 实现【最优资源分配】【2023Q1 200分】

一、题目描述 某块业务芯片最小容量单位为 1.25G&#xff0c;总容量为 M*1.25G&#xff0c;对该芯片资源编号为 1&#xff0c;2&#xff0c;… M。 该芯片支持 3 种不同的配置&#xff0c;分别为 A、B、C. 配置 A: 占用容量为 1.25 * 1 1.25G配置 B: 占用容量为 1.25* 2 2…

白嫖chatgpt的Edge插件,很难不爱啊

目录 &#x1f341;1.常见的Edge浏览器界面 &#x1f341;二.安装WebTab插件 &#x1f341;三.WebTab插件的各种功能 &#x1f341;1.支持免费的chatgpt&#xff0c;不限次数​编辑 &#x1f341;2.有几个休闲的小游戏可以玩耍&#xff0c;点击即玩。 &#x1f341;3.支…

【迷宫问题】找出迷宫所有可能的路径C++

1 引入情境 我记得小时候玩过推箱子游戏&#xff0c;也是如下图这种&#xff0c;四周由深色的方格作为墙壁&#xff0c;白色的地方是可以通过的。现在想要从红色方格出发走到黄色方格&#xff0c;能有什么好办法呢&#xff1f; 注意到&#xff0c;对于计算机没有全局的观念&…

Flutter音乐播放audioplayers

简介 Flutter的audioplayers是一个Flutter插件&#xff0c;可以播放多个同时的音频文件&#xff0c;支持Android、iOS、Linux、macOS、Windows和web平台。它有以下特点&#xff1a; 可以从本地文件、网络资源或内存中加载音频可以控制音量、进度、速度和循环可以播放多个音频…

《编程思维与实践》1069.第一位数字

《编程思维与实践》1069.第一位数字 题目 思路 由于正整数N的N次方最大可以为 1 0 8 ⋅ 1 0 8 10^{8\cdot 10^8} 108⋅108,加上数据可能有很多组,所以直接采用大整数计算次方这方法很可能超时, 这里给出一种数学算法: 幂指函数通常的处理方式是取对数将乘方转化为乘法: N N 1…

Linux驱动编程(驱动程序基石)(上)

一、休眠与唤醒 要休眠的线程&#xff0c;放在 wq 队列里&#xff0c;中断处理函数从 wq 队列里把它取出来唤醒。所以&#xff0c;我们要做这几件事&#xff1a; ① 初始化 wq 队列 ② 在驱动的 read 函数中&#xff0c;调用 wait_event_interruptible&#xff1a; 它本身会判断…