【找出所有稳定的二进制数组 I】python刷题记录

R4-每日一题.

今日甚是清醒.

目录

动态规划

记忆化搜索

递推方法

组合数学

容斥原理+乘法原理

ps:

贴题解

动态规划

记忆化搜索
python 复制代码
class Solution:
    def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
        MOD=1_000_000_007
        @cache
        def dfs(i,j,k):
            if i==0:
                return 1 if k==1 and j<=limit else 0
            if j==0:
                return 1 if k==0 and i<=limit else 0
            if k==0:
                return (dfs(i-1,j,0)+dfs(i-1,j,1)-(dfs(i-limit-1,j,1) if i>limit else 0))% MOD
            else:
                return (dfs(i,j-1,0)+dfs(i,j-1,1)-(dfs(i,j-limit-1,0) if j>limit else 0))% MOD
        ret=(dfs(zero,one,0)+dfs(zero,one,1)) % MOD
        #防止爆内存
        dfs.cache_clear()
        return ret
递推方法

就是将记忆化翻译成3维数组!

python 复制代码
class Solution:
    def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
        MOD=1_000_000_007
        #直接上3维数组
        f=[[[0,0] for _ in range(one+1)] for _ in range(zero+1)]
        for i in range(1,min(limit,zero)+1):
            f[i][0][0]=1
        for j in range(1,min(limit,one)+1):
            f[0][j][1]=1
        for i in range(1,zero+1):
            for j in range(1,one+1):
                f[i][j][0]=(f[i-1][j][0]+f[i-1][j][1]-(f[i-limit-1][j][1] if i>limit else 0))%MOD
                f[i][j][1]=(f[i][j-1][0]+f[i][j-1][1]-(f[i][j-limit-1][0] if j>limit else 0))%MOD
        return sum(f[-1][-1])%MOD

组合数学

容斥原理+乘法原理

这是人能想出来的吗??!!

python 复制代码
class Solution:
    def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:
        MOD=1_000_000_007
        MX=1001
 
        #f[i]=i! 阶乘
        fac=[0]*MX
        fac[0]=1
        for i in range(1,MX):
            fac[i]=fac[i-1]*i%MOD
        
        #inv_f[i]=i!^-1
        inv_f=[0]*MX
        inv_f[-1]=pow(fac[-1],-1,MOD)
        for i in range(MX-1,0,-1):
            inv_f[i-1]=inv_f[i]*i%MOD
        
        #最终计算(n m)
        def comb(n,m):
            return fac[n]*inv_f[m]*inv_f[n-m]%MOD
        
        if zero>one:
            # 保证空间复杂度为 O(min(zero, one))
            zero,one=one,zero
        f0=[0]*(zero+3)
        for i in range((zero-1)//limit+1,zero+1):
            f0[i]=comb(zero-1,i-1)
            for j in range(1,(zero-i)//limit+1):
                f0[i]=(f0[i]+(-1 if j%2 else 1)*comb(i,j)*comb(zero-j*limit-1,i-1))%MOD
        
        ret=0
        for i in range((one-1)//limit+1,min(one,zero+1)+1):
            f1=comb(one-1,i-1)
            for j in range(1,(one-i)//limit+1):
                f1=(f1+(-1 if j %2 else 1)*comb(i,j)*comb(one-j*limit-1,i-1))%MOD
            ret=(ret+(f0[i-1]+f0[i]*2+f0[i+1])*f1)%MOD
        return ret

灵神真的厉害!

ps:

1.

python 复制代码
#防止整数溢出     
MOD=1_000_000_007
%MOD   
python 复制代码
#记忆化搜索
@cache
python 复制代码
#防止爆内存
dfs.cache_clear()

2.

​​​​​​​3.

刷完后再润灵神题单(争取开学前干完?!)

灵神题单

相关推荐
松涛和鸣14 小时前
14、C 语言进阶:函数指针、typedef、二级指针、const 指针
c语言·开发语言·算法·排序算法·学习方法
yagamiraito_16 小时前
757. 设置交集大小至少为2 (leetcode每日一题)
算法·leetcode·go
程序员杰哥16 小时前
Python自动化测试之线上流量回放:录制、打标、压测与平台选择
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·压力测试
吴佳浩16 小时前
LangChain v1 重大更新讲解⚠⚠⚠
python·langchain·agent
星释16 小时前
Rust 练习册 57:阿特巴什密码与字符映射技术
服务器·算法·rust
星期天216 小时前
3.0 C语⾔内存函数:memcpy memmove memset memcmp 数据在内存中的存储:整数在内存中的存储 ⼤⼩端字节序和字节序判断
c语言·数据结构·进阶·内存函数·数据内存存储
无敌最俊朗@16 小时前
力扣hot100-141.环形链表
算法·leetcode·链表
智商低情商凑18 小时前
Go学习之 - Goroutines和channels
开发语言·学习·golang
半桶水专家18 小时前
Go 语言时间处理(time 包)详解
开发语言·后端·golang
编程点滴18 小时前
Go 重试机制终极指南:基于 go-retry 打造可靠容错系统
开发语言·后端·golang