2021-04-04:给定一个非负数组arr,和一个正数m。 返回arr的所有子序列中累加和%m之后的最大值。
2021-04-04:给定一个非负数组arr,和一个正数m。 返回arr的所有子序列中累加和%m之后的最大值。
福大大 答案2021-04-04:
自然智慧即可。
1.递归,累加和。
2.动态规划,累加和。
3.动态规划,累加和%m。
4.双向动态规划,累加和%m。
代码用golang编写。代码如下:
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func main() {
rand.Seed(time.Now().Unix())
const TOTAL = 500
RightCount := 0
for i := 0; i < TOTAL; i++ {
arr := NewRandArr()
m := rand.Intn(200) + 1
fmt.Println(arr, m)
ret1 := max1(arr, m)
fmt.Println("1.递归,累加和:", ret1)
ret2 := max2(arr, m)
fmt.Println("2.动态规划,累加和:", ret2)
ret3 := max3(arr, m)
fmt.Println("3.动态规划,累加和%m:", ret3)
ret4 := max4(arr, m)
fmt.Println("4.双向动态规划,累加和%m:", ret4)
fmt.Println("---------------------")
if ret1 == ret2 && ret1 == ret3 && ret1 == ret4 {
RightCount++
}
}
fmt.Println("总数:", TOTAL)
fmt.Println("正确:", RightCount)
}
//递归,算出所有子序列的累加和
func max1(arr []int, m int) int {
set := make(map[int]struct{})
process(arr, 0, 0, set)
max := 0
for sum, _ := range set {
max = getMax(max, sum%m)
}
return max
}
func process(arr []int, index int, sum int, set map[int]struct{}) {
if index == len(arr) {
set[sum] = struct{}{}
} else {
process(arr, index+1, sum, set)
process(arr, index+1, sum+arr[index], set)
}
}
func getMax(a int, b int) int {
if a > b {
return a
} else {
return b
}
}
//2.动态规划,算出所有的累加和
func max2(arr []int, m int) int {
sum := 0
N := len(arr)
for i := 0; i < N; i++ {
sum += arr[i]
}
dp := make([][]bool, N)
for i := 0; i < N; i++ {
dp[i] = make([]bool, sum+1)
}
for i := 0; i < N; i++ {
dp[i][0] = true
}
dp[0][arr[0]] = true
for i := 1; i < N; i++ {
for j := 1; j <= sum; j++ {
dp[i][j] = dp[i-1][j]
if j-arr[i] >= 0 {
dp[i][j] = dp[i][j] || dp[i-1][j-arr[i]]
}
}
}
ans := 0
for j := 0; j <= sum; j++ {
if dp[N-1][j] {
ans = getMax(ans, j%m)
}
}
return ans
}
//3.动态规划,算出所有的模m的累加和。数组长度巨大,m不大。
func max3(arr []int, m int) int {
N := len(arr)
// 0...m-1
dp := make([][]bool, N)
for i := 0; i < N; i++ {
dp[i] = make([]bool, m)
}
for i := 0; i < N; i++ {
dp[i][0] = true
}
dp[0][arr[0]%m] = true
for i := 1; i < N; i++ {
for j := 1; j < m; j++ {
// dp[i][j] T or F
dp[i][j] = dp[i-1][j]
cur := arr[i] % m
if cur <= j {
dp[i][j] = dp[i][j] || dp[i-1][j-cur]
} else {
dp[i][j] = dp[i][j] || dp[i-1][m+j-cur]
}
}
}
ans := 0
for i := 0; i < m; i++ {
if dp[N-1][i] {
ans = i
}
}
return ans
}
// 如果arr的累加和很大,m也很大
// 但是arr的长度相对不大
func max4(arr []int, m int) int {
if len(arr) == 1 {
return arr[0] % m
}
mid := (len(arr) - 1) / 2
sortSet1 := make(map[int]struct{})
process4(arr, 0, 0, mid, m, sortSet1)
sortSet2 := make(map[int]struct{})
process4(arr, mid+1, 0, len(arr)-1, m, sortSet2)
ans := 0
s1 := make([]int, 0)
for key, _ := range sortSet1 {
s1 = append(s1, key)
}
sort.Ints(s1)
//fmt.Println("s1:", s1)
s2 := make([]int, 0)
for key, _ := range sortSet2 {
s2 = append(s2, key)
}
sort.Ints(s2)
//fmt.Println("s2:", s2)
for _, leftMod := range s1 {
//ans = getMax(ans, leftMod + sortSet2.floor(m - 1 - leftMod));
index := NearestIndex2(s2, m-1-leftMod)
if index >= 0 {
ans = getMax(ans, leftMod+s2[index])
} else {
ans = getMax(ans, leftMod)
}
}
return ans
}
// 在arr上,找满足<=value的最右位置
func NearestIndex2(arr []int, v int) int {
L := 0
R := len(arr) - 1
index := -1 // 记录最右的对号
for L <= R {
mid := L + (R-L)>>1
if arr[mid] <= v {
index = mid
L = mid + 1
} else {
R = mid - 1
}
}
return index
}
// 从index出发,最后有边界是end+1,arr[index...end]
func process4(arr []int, index int, sum int, end int, m int, sortSet map[int]struct{}) {
if index == end+1 {
sortSet[sum%m] = struct {
}{}
} else {
process4(arr, index+1, sum, end, m, sortSet)
process4(arr, index+1, sum+arr[index], end, m, sortSet)
}
}
func NewRandArr() []int {
arrLen := rand.Intn(10) + 5
arr := make([]int, arrLen)
for i := 0; i < arrLen; i++ {
arr[i] = rand.Intn(50)
}
return arr
}
执行结果如下:

2021-04-04:给定一个非负数组arr,和一个正数m。 返回arr的所有子序列中累加和%m之后的最大值。的更多相关文章
- 给一个非矩形数组(Nonrectangular Arrays)
Nonrectangular Arrays(非矩形数组) public class Test { public static void main(String[] args) { ...
- 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。
从第0行开始,输出第k行,传的参数为第几行,所以在方法中先将所传参数加1,然后将最后一行加入集合中返回. 代码如下: public static List<Integer> generat ...
- 提交一个变量或数组到另一个jsp页面
注意一:提交一个变量到另一个jsp页面,用hidden的input 另一个页面用request.getParameter();获取 注意二:提交一个数组到另一个页面,可以用相同的input的n ...
- 如何用一个for循环打印出一个二维数组
思路分析: 二维数组在内存中默认是按照行存储的,比如一个二维数组{{1,2,3,},{4,5,6}},它在内存中存储的顺序就是1.2.3.4.5.6,也就是说,对于这6个数组元素,按照从0到5给它们编 ...
- 给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 ,返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况)
""" #给定一个只包含正整数的非空数组,返回该数组中重复次数最多的前N个数字 #返回的结果按重复次数从多到少降序排列(N不存在取值非法的情况) 解题思路: 1.设定一个 ...
- 语义分割(semantic segmentation) 常用神经网络介绍对比-FCN SegNet U-net DeconvNet,语义分割,简单来说就是给定一张图片,对图片中的每一个像素点进行分类;目标检测只有两类,目标和非目标,就是在一张图片中找到并用box标注出所有的目标.
from:https://blog.csdn.net/u012931582/article/details/70314859 2017年04月21日 14:54:10 阅读数:4369 前言 在这里, ...
- [饭后算法系列] 数组中"和非负"的最长子数组
1. 问题 给定一列数字数组 a[n], 求这个数组中最长的 "和>=0" 的子数组. (注: "子数组"表示下标必须是连续的. 另一个概念"子 ...
- 2021.11.04 P1392 取数(多路归并)
2021.11.04 P1392 取数(多路归并) P1392 取数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 在一个n行m列的数阵中,你须在每一行取一个数(共n个数) ...
- NET的堆和栈04,对托管和非托管资源的垃圾回收以及内存分配
在" .NET的堆和栈01,基本概念.值类型内存分配"中,了解了"堆"和"栈"的基本概念,以及值类型的内存分配.我们知道:当执行一个方法的时 ...
- Python算法每日一题--001--给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. 你可以不使用额外空间来实现吗? 示例 1: 输入: [ ...
随机推荐
- Keil Jlink没法找到STM32H750
https://www.amobbs.com/thread-5713382-1-1.html MDK使用的是5.32,jlink使用的是9.2jlink驱动使用的是6.44b 删除工程下的JLinkS ...
- 三天吃透MySQL面试八股文
本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...
- Mathematica的Combinatorica`程序包使用笔记
目录 官方给出的程序包使用指南和一些示例 引论 步骤 0x00 导入程序包 0x01 Integer Partitions 0x02 Integer Compositions 0x03 partiti ...
- PGF 概率生成函数 Probability generating function
Probability Mass Function 离散随机变量的分布函数PMF 目录 随机结构举例 two classical combinatorial distributions PGF Pro ...
- Linux设备驱动那些事
目的 初步了解 linux 设备驱动框架模型 初步了解设备驱动模型有哪些元素 设备驱动模型元素的说明及解释 设备驱动模型元素的工作原理 设备驱动模型的小例子 对整体有个粗略的了解,设备驱动类型种类太多 ...
- .Net 6.0定义全局当前身份缓存对象
背景: 当前身份缓存对象顾名思义就是:当前登录的用户身份对象,那它解决了什么问题呢?其实在我们日常开发过程中经常能用的到几乎是必备的,就比如我给某个表插入数据时需要创建人或者一些权限的访问,都得用到当 ...
- Django笔记十一之外键查询优化select_related和prefetch_related
本篇笔记目录如下: select_related prefetch_related 在介绍 select_related 和 prefetch_related 这两个函数前,我们先来看一个例子. 对于 ...
- Kafka存储内幕详解
1.概述 随着微服务和分布式计算的出现,Kafka已经成为各种主流平台系统架构中不可缺少的组成部分了.在本篇文章中,笔者将尝试为大家来解密Kafka的内部存储机制是如何运作的. 2.内容 在分布式系统 ...
- [Java SE]JDK版本特性解读:@PostStruct[JDK1.6-JDK1.8]
1 @PostStruct 1.1 概述 定义及用途 @PostConstruct(javax.annotation.PostConstruct)注解好多人以为是Spring提供的.而实际上是Java ...
- 【HALF】CSP-S2 2022 游记 - Dawn Eve?
相册放在 NOIP2022 游记 了 Day -2 周三.折腾了好几天,考场从深圳换到广州最后换到东莞.疫情爆炸... 只是希望自己最后两场比赛不会受到影响. 下午是高二体锻课,结果我们得去做核酸.四 ...