美文网首页
[50]小Q的歌单-腾讯2018秋

[50]小Q的歌单-腾讯2018秋

作者: jdzhangxin | 来源:发表于2018-11-08 19:53 被阅读28次

    1.题目描述

    小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,
    请问有多少种组成歌单的方法。

    • 输入描述:
      每个输入包含一个测试用例。
      每个测试用例的第一行包含一个整数,表示歌单的总长度 K(1<=K<=1000)。
      接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量 X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B
    • 输出描述:
      输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对 1000000007 取模的结果。
    • 输入示例:
      5
      2 3 3 3
      
    • 输出示例:
      9
      

    2.题目解析

    将两种长度的歌的数量进行遍历,如果满足总长度为K,计算该数量的组合C_n^m下共有多少种不同歌曲的组合方式。所以本题的关键是实现组合函数。

    C_n^m = \frac{n!}{m!(n-m)!}\qquad

    一般来说,时间复杂度是阶乘级O(n!)的函数是不可用的。这里需要用到杨辉三角。

    • 杨辉三角与组合之间的关系:
      组合的递推公式C_n^m = C_{n-1}^m + C_{n-1}^{m-1}
    杨辉三角

    从上图可见,杨辉三角保存着所有组合数。所以,只要把部分杨辉三角保存起来,求解组合直接查表。对应的C[m][n]就是C_n^m

    数学上规定0!=1

    3.参考答案

    #include <bits/stdc++.h>
    using namespace std;
    long long c[101][101]; // 保存杨辉三角
    const int mod = 1000000007;
    
    void init(int size) {
      c[0][0] = 1;
      for (int i = 1; i != size; i++) {
        c[i][0] = 1;
        for (int j = 1; j != size; j++){
          // 杨辉三角规则:当前值是上一行的两个肩上的值之和
          c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
        }
      }
    }
    int main() {
        // 构建杨辉三角
        init(101);
        // 获取输入参数
        int k = 0;// 歌单总长度
        scanf("%d",&k);
        int a = 0; // 第一种歌曲长度
        int x = 0; // 第一种歌曲数量
        int b = 0; // 第二种歌曲长度
        int y = 0; // 第二种歌曲数量
        scanf("%d%d%d%d",&a,&x,&b,&y);
        
        int res=0;
        // 遍历第一种歌曲数量可选用的数目0~x
        for (int i = 0; i <= x; i++) {
            int sum_a = i*a; // 第一种歌曲长度和
            int sum_b = k-i*a; // 第二种歌曲长度和
            if (sum_a <= k // 选取的第一种歌曲长度和不超过歌单总长度
                && sum_b%b == 0 // 除去第一种歌曲长度和,剩余长度必须是第二种歌曲长度的整数倍
                && sum_b/b <= y // 第二种歌曲数目不能超过歌曲总数
               ){
               // 组成歌单数目
               int count = (c[x][i] * c[y][sum_b/b]) % mod;
               res = (res + count) % mod; // 因为可能不止一种方式,多种方式数目累加。
            }
        }
        printf("%d\n", res);
      return 0;
    }
    

    牛客题目

    相关文章

      网友评论

          本文标题:[50]小Q的歌单-腾讯2018秋

          本文链接:https://www.haomeiwen.com/subject/hghqoftx.html