• 组合数学or not ---- n选k有重


    模板问题:

    1. 取物品 (comb.pas/c/cpp)

    【问题描述】 现在有n个物品(有可能相同),请您编程计算从中取k个有多少种不同的取法。
    【输入】 输入文件有两行,第一行包含两个整数n,k(2<=n<=30,0<=k<=n)。第二行,包含n个整数表示物品的编号(范围1..1000)。编号相同的物品看作同一种物品。

    想想看,组合数学中有这样的模型吗?答案是,肯定会有的.但是因为这个问题的灵活性,还没有通项公式.

    想象当每个数都不同时,这个问题就变成了${n choose k}$(即$ ext{C}^{k}_{n}$).如果只有一种物体呢?显然是$1$种可能.每种物体都大于等于$k$?就是$n^k$,因为k次选择每次都可以选$1~n$.

    但是这里是一般化的情况:(RT)

    自然,对于这个数据搜索只能勉强卡过.那么递推呢?递推一般对于解决排列解决问题很有用.那么我们设

    $fleft[ i,p ight]$为前i种选p个的方案数,那么

    $f[i,p]=sum_{k=0}^{ ext{min}left( N[i],p ight)}f[i-1,p-k] ext{ while here }ple sum_{j=1}^{i}N[j]$

    初始状态$forall i in [1,n],f[i,0]=1$(这个很重要)

    自然,我们可以用滚动数组优化空间,因为所有$f[i,k]$只与$f[i-1,d]$有关,且$dle k$,这时可以用类似于优化背包问题的办法.这个时间复杂度为$ ext{O}left( nkp ight)$但是注意这里$p$会比$n$大很多.

    再考虑优化.注意到sum是连续的,即可用前缀和优化.那么时间复杂度小了一个$p$.

  • 相关阅读:
    SpringBoot 断点调试无效问题解决
    oracle数据库入门
    IPFS入门
    Spring安全参考
    什么是内存泄漏?该如何检测?又该如何解决?
    coredump
    同一个程序在一个系统中可以跑起来,在另外一个系统上跑不起来
    dpkg 强制安装deb文件
    日志文件丢失
    文件句柄资源
  • 原文地址:https://www.cnblogs.com/tmzbot/p/3929632.html
Copyright © 2020-2023  润新知