2023-06-04:你的音乐播放器里有 N 首不同的歌,

在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复,

请你为她按如下规则创建一个播放列表,

每首歌至少播放一次,

一首歌只有在其他 K 首歌播放完之后才能再次播放。

返回可以满足要求的播放列表的数量。

由于答案可能非常大,请返回它模 10^9 + 7 的结果。

输入:n = 3, goal = 3, k = 1。

输出:6。

答案2023-06-04:

大体步骤如下:

1.定义常量MOD和LIMIT,分别表示模数和阶乘表的最大值。

2.定义全局变量FAC和INV,分别表示阶乘表和阶乘结果的乘法逆元表。

3.编写init函数,用于初始化FAC和INV数组。在该函数中先将FAC[0]和INV[0]赋值为1,然后使用循环计算FAC[i](i从1到LIMIT)的值,并使用费马小定理倒推计算出INV[i](i从LIMIT到2)的值。

4.编写power函数,用于计算x的n次方并对MOD取模后的结果。

5.编写numMusicPlaylists函数,根据题目要求计算可以满足要求的播放列表数量。该函数中定义三个int64类型变量:cur、ans和sign。cur用于保存当前循环中需要累加到答案中的部分,ans则是最终结果。sign初始为1,在每次循环结束时将其乘以-1来实现交替相加或相减。

6.numMusicPlaylists函数中使用一个for循环遍历i从0到n-k。在每次循环中,首先计算cur = sign * pow(n-k-i, l-k) % MOD。其中pow函数调用了power函数来计算幂次方。

7.然后将cur乘以FAC[n]、INV[i]、INV[n-k-i]并分别对MOD取模,更新cur的值。

8.将cur加到ans中并对MOD取模,最后返回ans的int类型值。

时间复杂度:$O(n2)$,其中n为歌曲数量。需要计算阶乘表和阶乘结果的乘法逆元表,时间复杂度均为O(n)。在numMusicPlaylists函数中使用了一个for循环,循环次数为n-k,每次循环中调用了power函数,时间复杂度为$O(logMOD)$,然后进行了常数次乘、除和取模运算,时间复杂度为O(1)。因此总时间复杂度为$O(n*(n-k)*logMOD)=O(n2*logMOD)$。

空间复杂度:O(n),主要是用来存储阶乘表和阶乘结果的乘法逆元表。

go完整代码如下:

package main

import "fmt"

const MOD int64 = 1000000007
const LIMIT int = 100 // 阶乘表
var FAC [LIMIT + 1]int64 // 阶乘结果的乘法逆元表
var INV [LIMIT + 1]int64 func init() {
FAC[0] = 1
INV[0] = 1
for i := 1; i <= LIMIT; i++ {
FAC[i] = (int64(i) * FAC[i-1]) % MOD
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
INV[LIMIT] = power(FAC[LIMIT], int(MOD-2))
for i := LIMIT; i > 1; i-- {
INV[i-1] = (int64(i) * INV[i]) % MOD
}
} // x的n次方,% mod之后,是多少?
func power(x int64, n int) int64 {
ans := int64(1)
for n > 0 {
if n&1 == 1 {
ans = (ans * x) % MOD
}
x = (x * x) % MOD
n >>= 1
}
return ans
} func numMusicPlaylists(n int, l int, k int) int {
var cur, ans, sign int64 = 0, 0, 1
for i := 0; i <= n-k; i++ {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * -1 -> mod - 1
cur = (sign * power(int64(n-k-i), l-k)) % MOD
cur = (cur * FAC[n]) % MOD
cur = (cur * INV[i]) % MOD
cur = (cur * INV[n-k-i]) % MOD
ans = (ans + cur) % MOD
sign *= -1
}
return int(ans)
} func main() {
n := 3
goal := 3
k := 1
result := numMusicPlaylists(n, goal, k)
fmt.Println(result)
}

rust完整代码如下:

const MOD: i64 = 1_000_000_007;
const LIMIT: usize = 100; // 阶乘表
static mut FAC: [i64; LIMIT + 1] = [0; LIMIT + 1]; // 阶乘结果的乘法逆元表
static mut INV: [i64; LIMIT + 1] = [0; LIMIT + 1]; unsafe fn init() {
INV[0] = 1;
FAC[0] = 1;
for i in 1..=LIMIT {
FAC[i] = ((i as i64) * FAC[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
INV[LIMIT] = power(FAC[LIMIT], (MOD - 2) as i32);
for i in (2..=LIMIT).rev() {
INV[i - 1] = ((i as i64) * INV[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
fn power(mut x: i64, mut n: i32) -> i64 {
let mut ans = 1;
while n > 0 {
if (n & 1) == 1 {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
ans
} pub fn num_music_playlists(n: i32, goal: i32, k: i32) -> i32 {
unsafe {
init();
let mut cur;
let mut ans = 0;
let mut sign = 1;
for i in 0..=n - k {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * -1 -> mod - 1
cur = (sign * power(n as i64 - k as i64 - i as i64, goal as i32 - k)) % MOD;
cur = (cur * FAC[n as usize]) % MOD;
cur = (cur * INV[i as usize]) % MOD;
cur = (cur * INV[(n - k - i) as usize]) % MOD;
ans = (ans + cur) % MOD;
sign *= -1;
}
ans as i32
}
} fn main() {
let n = 3;
let goal = 3;
let k = 1;
let result = num_music_playlists(n, goal, k);
println!("{}", result);
}

c++完整代码如下:

#include <iostream>
#include <vector> using namespace std; const int MOD = 1000000007;
const int LIMIT = 100; // 阶乘表
vector<int64_t> fac(LIMIT + 1); // 阶乘结果的乘法逆元表
vector<int64_t> inv(LIMIT + 1); int64_t pow2(int64_t x, int n); void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i <= LIMIT; i++) {
fac[i] = ((int64_t)i * fac[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
inv[LIMIT] = pow2(fac[LIMIT], MOD - 2);
for (int i = LIMIT; i > 1; i--) {
inv[i - 1] = ((int64_t)i * inv[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
int64_t pow2(int64_t x, int n) {
int64_t ans = 1;
while (n > 0) {
if (n & 1) {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
return ans;
} int numMusicPlaylists(int n, int l, int k) {
int64_t cur, ans, sign = 1;
ans = 0; for (int i = 0; i <= n - k; ++i, sign = sign == MOD - 1 ? 1 : MOD - 1) {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * MOD-1 -> mod - 1
cur = (sign * pow2(n - k - i, l - k)) % MOD;
cur = (cur * fac[n]) % MOD;
cur = (cur * inv[i]) % MOD;
cur = (cur * inv[n - k - i]) % MOD;
ans = (ans + cur) % MOD;
} return ans;
} int main() {
init();
int n = 3, goal = 3, k = 1;
int result = numMusicPlaylists(n, goal, k);
cout << result << endl; return 0;
}

c完整代码如下:

#include <stdio.h>
#include <stdint.h> #define MOD 1000000007
#define LIMIT 100 // 阶乘表
int64_t fac[LIMIT + 1]; // 阶乘结果的乘法逆元表
int64_t inv[LIMIT + 1]; int64_t pow2(int64_t x, int n); void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i <= LIMIT; i++) {
fac[i] = ((int64_t)i * fac[i - 1]) % MOD;
}
// 费马小定理计算乘法逆元,优化如下
// 这一块叫:阶乘的逆元倒推
inv[LIMIT] = pow2(fac[LIMIT], MOD - 2);
for (int i = LIMIT; i > 1; i--) {
inv[i - 1] = ((int64_t)i * inv[i]) % MOD;
}
} // x的n次方,% mod之后,是多少?
int64_t pow2(int64_t x, int n) {
int64_t ans = 1;
while (n > 0) {
if (n & 1) {
ans = (ans * x) % MOD;
}
x = (x * x) % MOD;
n >>= 1;
}
return ans;
} int numMusicPlaylists(int n, int l, int k) {
int64_t cur, ans, sign = 1;
ans = 0; for (int i = 0; i <= n - k; ++i, sign = sign == MOD - 1 ? 1 : MOD - 1) {
// cur ->
// FAC[n] -> n! % mod 的结果!
// INV[i] -> i! 的逆元!
// INV[n - k - i] -> (n - k - i)! 的逆元
// sign * 1 -> 1
// * MOD-1 -> mod - 1
cur = (sign * pow2(n - k - i, l - k)) % MOD;
cur = (cur * fac[n]) % MOD;
cur = (cur * inv[i]) % MOD;
cur = (cur * inv[n - k - i]) % MOD;
ans = (ans + cur) % MOD;
} return ans;
} int main() {
init();
int n = 3, goal = 3, k = 1;
int result = numMusicPlaylists(n, goal, k);
printf("%d\n", result); return 0;
}

2023-06-04:你的音乐播放器里有 N 首不同的歌, 在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复, 请你为她按如下规则创建一个播放列表, 每首歌至少播放一次, 一首歌只有在的更多相关文章

  1. Asp.Net MVC中Aplayer.js音乐播放器的使用

    1.前言: Aplater.js是一款可爱.漂亮的Js音乐播放器,以前就了解过也弄过一些,现在就用mp3的格式来在.Net里面开发.管网 https://aplayer.js.org/ 2.入手: 在 ...

  2. 历上最强的音乐播放器(jetA…

    原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...

  3. [转载]历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX

    原文地址:历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉化版)下载作者:盖世天星 历上最强的音乐播放器(jetAudio-8.0.5.320-Plus-VX-完全汉 ...

  4. Android基于发展Service音乐播放器

    这是一个基于Service组件的音乐播放器,程序的音乐将会由后台的Service组件负责播放,当后台的播放状态改变时,程序将会通过发送广播通知前台Activity更新界面:当用户单击前台Activit ...

  5. Android应用--简、美音乐播放器获取专辑图片(自定义列表适配器)

    Android应用--简.美音乐播放器获取专辑图片(自定义列表适配器) 2013年7月3日简.美音乐播放器开发 第二阶段已增加功能: 1.歌词滚动显示 2.来电监听 3.音量控制 4.左右滑动切换歌词 ...

  6. Android大作业 --音乐播放器

    1.项目成员(本次作业主要对上一次的音乐播放器进行完善) 韦家城 学号:1600802026 班级:161  博客:https://www.cnblogs.com/ln9969cc/ 邓乾尧 学号:1 ...

  7. 推荐美丽的flash网页MP3音乐播放器

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/491 在网页制作中.假设想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时 ...

  8. 搭建rtmp直播流服务之4:videojs和ckPlayer开源播放器二次开发(播放rtmp、hls直播流及普通视频)

    前面几章讲解了使用 nginx-rtmp搭建直播流媒体服务器; ffmpeg推流到nginx-rtmp服务器; java通过命令行调用ffmpeg实现推流服务; 从数据源获取,到使用ffmpeg推流, ...

  9. Movist for Mac(高清媒体播放器)v2.0.7中文特别版

    Movist for Mac中文破解版是目前Mac平台上最好用的视频播放器,功能强大简单好用.movist mac版拥有美观简洁的用户界面,提供多种功能,支持视频解码加速高品质的字幕,全屏幕浏览,是与 ...

  10. 【U3D】播放器设置(PlayerSettings)

    播放器设置 (Player Settings) 播放器设置 (Player Settings) 用于为您要在 Unity 中编译的最终游戏定义各项(特定于平台的)参数.例如,参数中的一些值用于您打开单 ...

随机推荐

  1. 多源异构数据信息的融合方式0 - Dempster/Shafer 证据理论(D-S证据理论)

    Dempster/Shafer 证据理论(D-S证据理论)的大体内容如下: 一.简介: 在理论中,由互不相容的基本命题组成的完备集合Θ称为识别框架,表示对于某一问题的所有可能答案,但是只有一个答案是正 ...

  2. Java 魔法值处理的四种方法

    Java 魔法值处理方案 魔法值的定义 方法一 静态常量(不推荐) 方法二 接口中定义 方法三 定义在实体类 方法四 使用枚举类 enum 总结 魔法值的定义 魔法值是Java中突兀出现在代码中的常量 ...

  3. 记一次MySQL5初始化被kill的问题排查

    写在前面 由于测试环境JED申请比较繁琐,所以Eone提供了单机版Mysql供用户使用,近期Eone搭建Mysql5的时候发现莫名被kill了,容器规格是4C8G,磁盘30G 这不科学,之前都是可以的 ...

  4. 虹科分享|被困云端?虹科Redis企业版数据库来解救!

    数字化时代已然到来,各行企业奋起直追数字化进程.为应对数据爆炸式增长导致的数据负载,并保证降低成本,增加效益的前提下,提升企业运行程序的灵活性.在云上进行应用程序部署的新趋势,风头正劲! 但这种方式为 ...

  5. SSH 免秘钥登录

    yum -y install expect ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa for i in 192.168.1.11 1 ...

  6. c#中工厂模式详解

    总体介绍:   工厂模式主要有三种类型:简单工厂.工厂方法和抽象工厂,该模式用于封装和管理对象的创建,是一种创建型模式.   万物皆对象,创建对象时必然需要new该对象,当需要更改对象时,需要把项目中 ...

  7. HTML5学习内容-3

    (一)行高 line-height,一行文字的高度 例子 <!DOCTYPE html> <html lang="en"> <head> < ...

  8. gitlab : You won`t be able to pull or push project code via SSH until you add an SSH key to your profile(导致的问题:合并不了代码)

    gitlab : You won`t be able to pull or push project code via SSH until you add an SSH key to your pro ...

  9. Python入门--字符串

    字符串的使用和C语言 .java中一致 .使用" "(双引号)并且字符串可以与数字相乘,表示我使用这个字符串次数 字符串的连接:'+' Python中的变量直接赋值即可 ,如果赋予 ...

  10. C语言编写一个程序,从键盘读入一个矩形的两个边的值(整数),输出矩形面积。

    #include<stdio.h> int main() { int i, j, s;//定义矩形的长,宽,面积变量 scanf_s("%d,%d", &i, ...