2022-04-14:小美有一个长度为n的数组, 为了使得这个数组的和尽量大,她向会魔法的小团进行求助。 小团可以选择数组中至多两个不相交的子数组, 并将区间里的数全都变为原来的10倍。 小团想知道他

Posted 福大大架构师每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-04-14:小美有一个长度为n的数组, 为了使得这个数组的和尽量大,她向会魔法的小团进行求助。 小团可以选择数组中至多两个不相交的子数组, 并将区间里的数全都变为原来的10倍。 小团想知道他相关的知识,希望对你有一定的参考价值。

2022-04-14:小美有一个长度为n的数组,
为了使得这个数组的和尽量大,她向会魔法的小团进行求助。
小团可以选择数组中至多两个不相交的子数组,
并将区间里的数全都变为原来的10倍。
小团想知道他的魔法最多可以帮助小美将数组的和变大到多少?
来自美团。

答案2022-04-14:

动态规划。
时间复杂度:O(N)。
空间复杂度:O(N)。

代码用rust编写。代码如下:

#![feature(core_intrinsics)]
fn print_type_of<T>(_: T) 
    println!("", unsafe  std::intrinsics::type_name::<T>() );


fn main()
    let arr: Vec<i32> = vec![3, -4, 5, 1, -3];
    let ret:i32 = max_sum2(arr);
    println!("",ret);
    print_type_of(ret);



fn max_sum2(arr: Vec<i32>) ->i32 
	let n = arr.len();
	if n == 0 
		return 0;
	
	if n == 1 
		return get_max(arr[0], arr[0]*10);
	
	// dp[i]
	// 1) arr[0...i]原始累加和
	// 2) dp[i-1] + arr[i]
	// 3) magic[i]

	// : arr[0..i]范围上,可以没有10倍区域、或者有10倍区域但是最多有一个的情况下,
	//    最大累加和是多少?
	// 可能性1:就是没有10倍区域,那就是arr[0..i]的累加和, 这个好弄!
	//
	// 可能性2:有一个10倍区域
	//         a : arr[i]不在10倍区域里,但是之前可能有,那么就是dp[i-1] + arr[i]
	//
	//         b : arr[i]在10倍区域里
	//             甲:arr[0..i-1]没有10倍区域,arr[i]自己10倍,arr[0..i-1] + 10 * arr[i]
	//             乙:arr[0..i-1]中i-1位置在10倍区域里,arr[i]也在10倍区域里
	// magic[i] : magic[i] ..i  i
	// 对于乙,要求知道magic[j]的信息
	// magic[j]:arr[0..j]范围上,j一定要在10倍区域里,并且只有一个10倍区域的情况下,最大累加和
	// 可能性1:只有arr[j]是10倍,arr[0..j-1]没有10倍
	// 可能性2:magic[j-1] + 10 * arr[j]
	let mut sum :i32 = arr[(n-1) as usize];
	let mut magic:i32 = sum * 10;
    let mut right:Vec<i32> = Vec::new(); 
    for i in 0..n  
        right.push(0); 
     
    
	right[n-1] = get_max(sum, sum*10);

    let mut i:isize=n as isize -2 as isize;
	while i >= 0 
		magic = 10*arr[i as usize] + get_max(sum, magic);
		sum = sum + arr[i as usize];
		right[i as usize] = get_max(get_max(sum, right[i as usize + 1] + arr[i as usize]), magic);
        i = i - 1;
	
	let mut ans:i32 = right[0];
	sum = arr[0];
	magic = sum * 10;
	let mut dp:i32 = get_max(sum, sum * 10);
	ans = get_max(ans, dp + right[1]);
    i=1;
	while i < n as isize-1
		magic = 10 * arr[i as usize] + get_max(sum, magic);
		sum = sum + arr[i as usize];
		dp = get_max(get_max(sum, dp+arr[i as usize]), magic);
		ans = get_max(ans, dp + right[i as usize + 1]);
        i = i + 1;
	
	return ans;


fn get_max(a:i32, b :i32) ->i32 
	if a > b a else b

执行结果如下:

代码用golang编写。代码如下:

package main

import "fmt"

func main() 
	arr := []int3, -4, 5, 1, -3
	ret := maxSum2(arr)
	fmt.Println(ret)


func maxSum2(arr []int) int 
	n := len(arr)
	if n == 0 
		return 0
	
	if n == 1 
		return getMax(arr[0], arr[0]*10)
	
	// dp[i]
	// 1) arr[0...i]原始累加和
	// 2) dp[i-1] + arr[i]
	// 3) magic[i]

	// : arr[0..i]范围上,可以没有10倍区域、或者有10倍区域但是最多有一个的情况下,
	//    最大累加和是多少?
	// 可能性1:就是没有10倍区域,那就是arr[0..i]的累加和, 这个好弄!
	//
	// 可能性2:有一个10倍区域
	//         a : arr[i]不在10倍区域里,但是之前可能有,那么就是dp[i-1] + arr[i]
	//
	//         b : arr[i]在10倍区域里
	//             甲:arr[0..i-1]没有10倍区域,arr[i]自己10倍,arr[0..i-1] + 10 * arr[i]
	//             乙:arr[0..i-1]中i-1位置在10倍区域里,arr[i]也在10倍区域里
	// magic[i] : magic[i] ..i  i
	// 对于乙,要求知道magic[j]的信息
	// magic[j]:arr[0..j]范围上,j一定要在10倍区域里,并且只有一个10倍区域的情况下,最大累加和
	// 可能性1:只有arr[j]是10倍,arr[0..j-1]没有10倍
	// 可能性2:magic[j-1] + 10 * arr[j]
	sum := arr[n-1]
	magic := sum * 10
	right := make([]int, n)
	right[n-1] = getMax(sum, sum*10)
	for i := n - 2; i >= 0; i-- 
		magic = 10*arr[i] + getMax(sum, magic)
		sum += arr[i]
		right[i] = getMax(getMax(sum, right[i+1]+arr[i]), magic)
	
	ans := right[0]
	sum = arr[0]
	magic = sum * 10
	dp := getMax(sum, sum*10)
	ans = getMax(ans, dp+right[1])
	for i := 1; i < n-1; i++ 
		magic = 10*arr[i] + getMax(sum, magic)
		sum += arr[i]
		dp = getMax(getMax(sum, dp+arr[i]), magic)
		ans = getMax(ans, dp+right[i+1])
	
	return ans


func getMax(a, b int) int 
	if a > b 
		return a
	 else 
		return b
	


执行结果如下:


左神java代码

以上是关于2022-04-14:小美有一个长度为n的数组, 为了使得这个数组的和尽量大,她向会魔法的小团进行求助。 小团可以选择数组中至多两个不相交的子数组, 并将区间里的数全都变为原来的10倍。 小团想知道他的主要内容,如果未能解决你的问题,请参考以下文章

2022-11-22:小美将要期中考试,有n道题,对于第i道题, 小美有pi的几率做对,获得ai的分值,还有(1-pi)的概率做错,得0分。 小美总分是每道题获得的分数。 小美不甘于此,决定突击复习,

2023-01-02:某天,小美在玩一款游戏,游戏开始时,有n台机器, 每台机器都有一个能量水平,分别为a1a2…an, 小美每次操作可以选其中的一台机器,假设选的是第i台, 那小美可以将其变成

2022-12-12:有n个城市,城市从0到n-1进行编号。小美最初住在k号城市中 在接下来的m天里,小美每天会收到一个任务 她可以选择完成当天的任务或者放弃该任务 第i天的任务需要在ci号城市完成,

对数据长度为n的数组内的数据进行全排列,c语言

面试题3:在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为

2022-06-14:数组的最大与和。 给你一个长度为 n 的整数数组 nums 和一个整数 numSlots ,满足2 * numSlots >= n 。总共有 numSlots 个篮子,编号为 1