2023-10-11:用go语言,一个数字n,一定要分成k份, 得到的乘积尽量大是多少? 数字n和k,可能非常大,到达10^12规模。 结果可能更大,所以返回结果对1000000007取模。 来自华为
2023-10-11:用go语言,一个数字n,一定要分成k份,
得到的乘积尽量大是多少?
数字n和k,可能非常大,到达10^12规模。
结果可能更大,所以返回结果对1000000007取模。
来自华为。
来自左程云。
答案2023-10-11:
大体过程如下:
算法1:暴力递归
1.首先判断k是否为0或者n是否小于k,若是则返回-1。
2.调用递归函数process1,传入参数n和k。
3.在递归函数中,若k为1,则返回n。
4.使用循环从1到rest(即剩余数字n)遍历cur,cur为当前需要划分的数字。
5.将cur与process1(rest-cur, j-1)相乘,得到当前划分下的乘积curAns。
6.若curAns大于ans,则更新ans为curAns。
7.返回ans作为结果。
算法2:贪心的解
1.首先判断k是否为0或者n是否小于k,若是则返回-1。
2.计算每份应得数字a,为n除以k的商。
3.计算有多少份应该升级成a+1,并将结果保存到变量b中。
4.初始化ans为1。
5.使用循环从0到b遍历i,将a+1乘以ans,更新ans的值。
6.使用循环从0到k-b遍历i,将a乘以ans,更新ans的值。
7.返回ans作为结果。
算法3:贪心的解(最优解)
1.首先判断k是否为0或者n是否小于k,若是则返回-1。
2.初始化变量mod为1000000007。
3.计算每份应得数字a,为n除以k的商。
4.计算有多少份应该升级成a+1,并将结果保存到变量b中。
5.调用函数power(a+1, b, mod)计算part1,表示a+1的b次方的结果对mod取模。
6.调用函数power(a, k-b, mod)计算part2,表示a的k-b次方的结果对mod取模。
7.返回(part1 * part2) % mod作为结果。
总的时间复杂度:
算法1:暴力递归的时间复杂度可以用递归树来表示,假设n和k的差值为m(即n-k=m),则递归树的高度为m,每个节点需要进行O(m)的计算,所以总的时间复杂度为O(m^m)。
算法2和算法3的时间复杂度为O(1),因为只有常数次的运算。
总的空间复杂度:
算法1:暴力递归的空间复杂度为O(m),递归树的高度为m,所以递归所需的栈空间为O(m)。
算法2和算法3的空间复杂度为O(1),只需要常数个变量进行计算。
go完整代码如下:
package main
import "fmt"
// 暴力递归
// 一定能得到最优解
func maxValue1(n int, k int) int {
if k == 0 || n < k {
return -1
}
return process1(n, k)
}
// 剩余的数字rest,一定要拆成j份,返回最大乘积
func process1(rest int, j int) int {
if j == 1 {
return rest
}
// 10 , 3份
// 1 * f(9,2)
// 2 * f(8,2)
// 3 * f(7,2)
// ...
ans := -1 << 31
for cur := 1; cur <= rest && (rest-cur) >= (j-1); cur++ {
curAns := cur * process1(rest-cur, j-1)
if curAns > ans {
ans = curAns
}
}
return ans
}
// 贪心的解
// 这不是最优解,只是展示贪心思路
func maxValue2(n int, k int) int {
if k == 0 || n < k {
return -1
}
// 数字n,一定要分k份
// 每份先得多少,n/k
a := n / k
// 有多少份可以升级成a+1
b := n % k
ans := 1
for i := 0; i < b; i++ {
ans *= a + 1
}
for i := 0; i < k-b; i++ {
ans *= a
}
return ans
}
// 贪心的解
// 这是最优解
// 但是如果结果很大,让求余数...
func maxValue3(n int64, k int64) int {
if k == 0 || n < k {
return -1
}
mod := 1000000007
a := n / k
b := n % k
part1 := power(a+1, b, mod)
part2 := power(a, k-b, mod)
return int((part1 * part2) % int64(mod))
}
// 返回a的n次方,%mod的结果
func power(a int64, n int64, mod int) int64 {
ans := int64(1)
tmp := a
for n != 0 {
if (n & 1) != 0 {
ans = (ans * tmp) % int64(mod)
}
n >>= 1
tmp = (tmp * tmp) % int64(mod)
}
return ans
}
func main() {
// 可以自己来用参数实验
n := 20
k := 4
fmt.Println(maxValue1(n, k))
fmt.Println(maxValue2(n, k))
// fmt.Println(maxValue3(n, k))
}

rust完整代码如下:
fn max_value1(n: i32, k: i32) -> i32 {
if k == 0 || n < k {
return -1;
}
process1(n, k)
}
fn process1(rest: i32, j: i32) -> i32 {
if j == 1 {
return rest;
}
let mut ans = i32::MIN;
for cur in 1..=rest {
if (rest - cur) >= (j - 1) {
let cur_ans = cur * process1(rest - cur, j - 1);
ans = ans.max(cur_ans);
}
}
ans
}
fn max_value2(n: i32, k: i32) -> i32 {
if k == 0 || n < k {
return -1;
}
let a = n / k;
let b = n % k;
let mut ans = 1;
for _ in 0..b {
ans *= a + 1;
}
for _ in 0..(k - b) {
ans *= a;
}
ans
}
fn max_value3(n: i64, k: i64) -> i32 {
if k == 0 || n < k {
return -1;
}
let mod_val = 1000000007;
let a = n / k;
let b = n % k;
let part1 = power(a + 1, b, mod_val);
let part2 = power(a, k - b, mod_val);
(part1 * part2 % mod_val) as i32
}
fn power(a: i64, n: i64, mod_val: i64) -> i64 {
let mut ans = 1;
let mut tmp = a;
let mut n = n;
while n != 0 {
if n & 1 != 0 {
ans = ans * tmp % mod_val;
}
n >>= 1;
tmp = tmp * tmp % mod_val;
}
ans
}
fn main() {
let n = 20;
let k = 4;
println!("{}", max_value1(n, k));
println!("{}", max_value2(n, k));
println!("{}", max_value3(n as i64, k as i64));
}

c++完整代码如下:
#include <iostream>
using namespace std;
int process1(int rest, int j)
{
if (j == 1)
{
return rest;
}
int ans = INT_MIN;
for (int cur = 1; cur <= rest && (rest - cur) >= (j - 1); cur++)
{
int curAns = cur * process1(rest - cur, j - 1);
ans = max(ans, curAns);
}
return ans;
}
int maxValue1(int n, int k)
{
if (k == 0 || n < k)
{
return -1;
}
return process1(n, k);
}
int maxValue2(int n, int k)
{
if (k == 0 || n < k)
{
return -1;
}
int a = n / k;
int b = n % k;
int ans = 1;
for (int i = 0; i < b; i++)
{
ans *= a + 1;
}
for (int i = 0; i < k - b; i++)
{
ans *= a;
}
return ans;
}
int power(long long a, long long n, int mod)
{
long long ans = 1;
long long tmp = a;
while (n != 0) {
if ((n & 1) != 0)
{
ans = (ans * tmp) % mod;
}
n >>= 1;
tmp = (tmp * tmp) % mod;
}
return ans;
}
int maxValue3(long long n, long long k)
{
if (k == 0 || n < k)
{
return -1;
}
int mod = 1000000007;
long long a = n / k;
long long b = n % k;
long long part1 = power(a + 1, b, mod);
long long part2 = power(a, k - b, mod);
return (part1 * part2) % mod;
}
int main() {
int n = 20;
int k = 4;
cout << maxValue1(n, k) << endl;
cout << maxValue2(n, k) << endl;
cout << maxValue3(n, k) << endl;
return 0;
}

c完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 暴力递归
// 一定能得到最优解
int maxValue1(int n, int k) {
if (k == 0 || n < k) {
return -1;
}
return process1(n, k);
}
// 剩余的数字rest,一定要拆成j份,返回最大乘积
int process1(int rest, int j) {
if (j == 1) {
return rest;
}
// 10 , 3份
// 1 * f(9,2)
// 2 * f(8,2)
// 3 * f(7,2)
// ...
int ans = -INT_MAX;
for (int cur = 1; cur <= rest && (rest - cur) >= (j - 1); cur++) {
int curAns = cur * process1(rest - cur, j - 1);
if (curAns > ans) {
ans = curAns;
}
}
return ans;
}
// 贪心的解
// 这不是最优解,只是展示贪心思路
int maxValue2(int n, int k) {
if (k == 0 || n < k) {
return -1;
}
// 数字n,一定要分k份
// 每份先得多少,n/k
int a = n / k;
// 有多少份可以升级成a+1
int b = n % k;
int ans = 1;
for (int i = 0; i < b; i++) {
ans *= a + 1;
}
for (int i = 0; i < k - b; i++) {
ans *= a;
}
return ans;
}
long long power(long long a, long long n, int mod);
// 贪心的解
// 这是最优解
// 但是如果结果很大,让求余数...
int maxValue3(long long n, long long k) {
if (k == 0 || n < k) {
return -1;
}
int mod = 1000000007;
long long a = n / k;
long long b = n % k;
long long part1 = power(a + 1, b, mod);
long long part2 = power(a, k - b, mod);
return (int)((part1 * part2) % mod);
}
// 返回a的n次方,%mod的结果
long long power(long long a, long long n, int mod) {
long long ans = 1;
long long tmp = a;
while (n != 0) {
if ((n & 1) != 0) {
ans = (ans * tmp) % mod;
}
n >>= 1;
tmp = (tmp * tmp) % mod;
}
return ans;
}
int main() {
// 可以自己来用参数实验
int n = 20;
int k = 4;
printf("%d\n", maxValue1(n, k));
printf("%d\n", maxValue2(n, k));
//printf("%d\n", maxValue3(n, k));
return 0;
}

2023-10-11:用go语言,一个数字n,一定要分成k份, 得到的乘积尽量大是多少? 数字n和k,可能非常大,到达10^12规模。 结果可能更大,所以返回结果对1000000007取模。 来自华为的更多相关文章
- 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
include "stdafx.h" #include<iostream> #include<vector> #include <algorithm& ...
- App Store审核指南中文版(2014.10.11更新)
App Store审核指南中文版(2014.10.11更新) 2014-10-11 16:36 编辑: suiling 分类:AppStore研究 来源:CocoaChina 2 8657 App ...
- VMware 10安装Mac OS X 10.11和XCode7
上周把我的计算机当试验品,安装mac虚拟机.由于文件下载复制解压的时间花了很长,历时两天,记录下来(和我一样的新手不妨参考一下): 我机硬件:win7 64位 8G内存 没有8G以上就不要考虑了.我安 ...
- 关闭 OSX 10.11 SIP (System Integrity Protection) 功能
关闭 OSX 10.11 SIP (System Integrity Protection) 功能 来源 https://cms.35g.tw/coding/%E9%97%9C%E9%96%89-os ...
- HDU 5698 大组合数取模(逆元)
瞬间移动 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
- 剑指offer19:按照从外向里以顺时针的顺序依次打印出每一个数字,4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
1 题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印 ...
- LeetCode第496题:下一个更大元素 I
问题描述 给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集.找到 nums1 中每个元素在 nums2 中的下一个比其大的值. nums1 中数字 x ...
- lintcode-1174.下一个更大的元素 III
题目描述: 1174. 下一个更大的元素 III 给定一个32位整数n,用同样的数字组成新的32位整数,使得它要比n大,返回最小的这样的数.如果不存在这样的整数,返回-1. 算法思路: 首先将这个数转 ...
- 556. 下一个更大元素 III
556. 下一个更大元素 III 给定一个32位正整数 n,你需要找到最小的32位整数,其与 n 中存在的位数完全相同,并且其值大于n.如果不存在这样的32位整数,则返回-1. 示例 1: 输入: 1 ...
- [Swift]LeetCode496. 下一个更大元素 I | Next Greater Element I
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...
随机推荐
- 使用Blazor WASM实现可取消的多文件带校验并发分片上传
前言 上传大文件时,原始HTTP文件上传功能可能会影响使用体验,此时使用分片上传功能可以有效避免原始上传的弊端.由于分片上传不是HTTP标准的一部分,所以只能自行开发相互配合的服务端和客户端.文件分片 ...
- 查漏补缺,这些热门开源项目你都知道么?「GitHub 热点速览」
本期热点速览的周榜部分的项目,基本上每周都会在 GitHub Trending 见到它们的身影,因为它们实在太火了.一般来说,这些火爆的项目大家都耳熟能详,但是为了防止有些小伙伴不怎么逛 GitHub ...
- Java21上手体验-分代ZGC和虚拟线程
一.导语 几天前Oracle刚刚发布了Java21, 由于这是最新的LTS版本,引起了大家的关注. 我也第一时间在个人项目中进行了升级体验. 一探究竟,和大家分享. 二.Java21更新内容介绍 官方 ...
- 详述Java内存屏障,透彻理解volatile
一般来说内存屏障分为两层:编译器屏障和CPU屏障,前者只在编译期生效,目的是防止编译器生成乱序的内存访问指令:后者通过插入或修改特定的CPU指令,在运行时防止内存访问指令乱序执行. 下面简单说一下这两 ...
- 实战攻防演练--利用微软自带Certutil命令ByPassAV上传C2
Certutil Certutil.exe是Windows操作系统中的合法程序,主要用于管理证书相关操作.它提供了转储和显示证书颁发机构(CA)的配置信息.配置证书服务.备份和还原CA组件,以及验证证 ...
- Molecule 在构建工具中的选择
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:修能 朝闻道,夕死可矣 何为 Molecule? 轻量级的 ...
- 一张图搞懂sql执行顺序
冲浪时发现一张很有意思的图,细分了一个长sql语句的执行顺序
- 零基础快速上手STM32开发(手把手保姆级教程)
零基础快速上手STM32开发(手把手保姆级教程) 1. 前言 作为一名嵌入式工程师,STM32 是必须要学习的一款单片机,同时这款单片机资料足够多,而且比较简单,非常适合初学者入门. STM32 是一 ...
- JavaScript高级程序设计笔记05 基本引用类型
基本引用类型 引用值(对象)是某个特定引用类型的实例.引用类型是把数据和功能组织到一起的结构. 引用类型有时也被称为对象定义,因为它们描述了自己的对象应有的属性和方法. Date 参考了Java早期版 ...
- 数据库系列:RR和RC下,快照读的区别
数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库 ...