Leetcode 2954. Count the Number of Infection Sequences

2023-12-03 20:36

本文主要是介绍Leetcode 2954. Count the Number of Infection Sequences,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • Leetcode 2954. Count the Number of Infection Sequences
    • 1. 解题思路
    • 2. 代码实现
  • 题目链接:2954. Count the Number of Infection Sequences

1. 解题思路

这道题其实思路上还是挺简单的,就是一个数学问题,还是那种不太难的数学问题。

显然, m m m个生病的人将所有的 n n n个人分成了 n − m + 1 n-m+1 nm+1段,其中头尾两段的传播方向只能是单向的,而剩余的 m − 1 m-1 m1段则每一段都有 2 x i − 1 2^{x_i-1} 2xi1种传播序列( x i > 0 x_i>0 xi>0)。

此时,总的传播序列数目就为:

Π i = 1 m − 1 2 x i − 1 \mathop{\Pi}\limits_{i=1}^{m-1}2^{x_i-1} i=1Πm12xi1

然后,各段序列之间是可以有不同的组合方式的,而这个就是一个排列组合问题,对应的序列可能性就是:

Π i = 0 m C ∑ j ≤ i x i x i \mathop{\Pi}\limits_{i=0}^{m} \mathop{C}_{\sum\limits_{j \leq i} x_i}^{x_i} i=0ΠmCjixixi

将两式相乘即可得到我们总的可能的序列数目。

但是实际在做的时候一直遇到超时问题,因为 C n m = n ! m ! ( n − m ) ! C_n^m = \frac{n!}{m!(n-m)!} Cnm=m!(nm)!n!这个计算是很繁琐的,而且还有同余的问题,就一直处理不好。

最后是看了一下其他大佬的解答才豁然开朗,发现算法还是这么个算法,但是优化点在于说提前先算好 n ! n! n!并记录下来,然后对于 C n m C_n^m Cnm的计算就不用每次都反复求一遍了。

唉,感觉自己还是傻了……

2. 代码实现

给出python代码实现如下:

MOD = 10**9 + 7@lru_cache(None)
def get_facts():facts = [1 for _ in range(10**5+1)]for i in range(2, 10**5+1):facts[i] = i * facts[i-1] % MODreturn factsFACTS = get_facts()
def C(n, m):return FACTS[n] * pow(FACTS[m], -1, mod=MOD) * pow(FACTS[n-m], -1, mod=MOD) % MODclass Solution:def numberOfSequence(self, n: int, sick: List[int]) -> int:if len(sick) == n:return 0a, b = sick[0]-0, n-1-sick[-1]ans = 1 * C(a+b, a)s = a + bm = len(sick)for i in range(m-1):k = sick[i+1] - sick[i]-1if k > 0:s += kans = ans * pow(2, k-1, mod=MOD) * C(s, k) % MODreturn ans

提交代码评测得到:耗时404ms,占用内存20.6MB。

这篇关于Leetcode 2954. Count the Number of Infection Sequences的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/450792

相关文章

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

usaco 1.2 Name That Number(数字字母转化)

巧妙的利用code[b[0]-'A'] 将字符ABC...Z转换为数字 需要注意的是重新开一个数组 c [ ] 存储字符串 应人为的在末尾附上 ‘ \ 0 ’ 详见代码: /*ID: who jayLANG: C++TASK: namenum*/#include<stdio.h>#include<string.h>int main(){FILE *fin = fopen (

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return