• 校招真题练习033 音乐列表(贝壳)


    音乐列表

    题目描述
    小明喜欢在火车旅行的时候用手机听音乐,他有N首歌在手机里,在整个火车途中,他可以听P首歌,所以他想产生一个播放表产生P首歌曲,这个播放表的规则是:
    (1)每首歌都要至少被播放一次
    (2)在两首一样的歌中间,至少有M首其他的歌
    小明在想有多少种不同的播放表可以产生,那么给你N,M,P,你来算一下,输出结果取1000000007的余数

    输入描述:
    输入N,M,P
    N范围在1到100
    M范围在0到N
    P范围在N到100

    输出描述:
    输出结果mod 1000000007的余数

     1 import math
     2 n,m,p = map(int,input().split())
     3 dp = [[0 for _ in range(p+1)] for _ in range(n+1)]
     4 for i in range(m+1,n+1):
     5     for j in range(i,p+1):
     6         if j == i or i == m+1:
     7             dp[i][j] = math.factorial(i)
     8         else:
     9             dp[i][j] = dp[i-1][j-1] * i + dp[i][j-1] * (i-m)
    10 print(dp[n][p]%1000000007)

    算法思路:动态规划。

    本题目要计算的是,用n首不同的歌曲组成一个长度为p的歌曲列表,有多少种可能。

    其中有两个条件:

    1每首歌曲至少要播放一次,那必定p>=n,否则本条件无法满足,这个条件是隐含的,容易被忽略;

    2相同的两首歌中间,至少间隔m首其他的歌曲。

    举一个实际的例子来说明本题目的思路。假设n=4,m=2,p=5。

    定义dp[n+1][p+1]二维数组,初始值为0。每一个元素表示由i首歌组成长度为j的列表,有多少可能。显然dp[n][p]即为所求。

    i=0,表示有0首歌,其值都为0,表示不可能组成歌单。

    i=1,表示有1首歌,要分两种情况讨论:

      如果m=0,则值为1;如果m>=1,则值为0。本题m=2,因此值均为0。

    i=2,表示有2首歌,

      如果m=0,则2*2=4;如果m=1,则2*1=2;如果m>=2,则值为0。本题m=2,因此值为0。

    由以上分析可发现,从第0行到第m行的值均为0,那么只需要从第m+1行开始计算即可。见代码第4行:range(m+1,p+1)

    i=3,表示有3首歌,本题m=2,

      j=3,第一个位置有3种选择,第二个位置有2种选择,第二个位置有1种选择。见代码第7行math.factorial()计算阶乘。

      j=4,要计算的是3首歌生成一个长度为4的歌单,把此问题分成两部分考虑:

        第一部分,2首歌生成长度为3的歌单,间隔2首。左上 * i

        第二部分,3首歌生成长度为3的歌单,间隔2首。左 * (i - m)

      结果为两部分之和。

    但是为什么这样划分,我还没有想明白。只能先记录下来吧,也许以后能理解吧。

  • 相关阅读:
    pyqt动画的使用
    pyqt 自定义信号
    设计工具- QtDesigner
    样式控制-QSS 样式表
    布局管理之 QStackedLayout (堆 布局)
    布局管理之 QGridLayout (网格布局)
    布局管理之 QFormLayout (表单布局)
    看代码中
    公司同事好坑
    我要多开梦幻手游PC端(梦幻手游PC端多开的简单分析及实现办法)
  • 原文地址:https://www.cnblogs.com/asenyang/p/11326834.html
Copyright © 2020-2023  润新知