最多等和不相交连续子序列

一、题目描述

给定一个数组,我们称其中连续的元素为连续子序列,称这些元素的和为连续子序列的和。

数组中可能存在几组连续子序列,组内的连续子序列互不相交且有相同的和。

求一组连续子序列,组内子序列的数目最多。输出这个数目。

二、输入输出描述

输入描述

  • 第一行:数组长度 N,1 <= N <= 10^3;
  • 第二行:N 个用空格分开的整数 Ci,-10^5 <= Ci <= 10^5。

输出描述

  • 一个整数 M,表示满足要求的最多的组内子序列的数目。

三、示例

|----|-------------------------------------------|
| 输入 | 10 8 8 9 1 9 6 3 9 1 0 |
| 输出 | 4 |
| 说明 | 四个子序列的第一个元素和最后一个元素的下标分别为: 2 2 4 4 5 6 7 7 |

|----|---------------------------------------|
| 输入 | 10 -1 0 4 -3 6 5 -6 5 -7 -3 |
| 输出 | 3 |
| 说明 | 三个子序列的第一个元素和最后一个元素的下标分别为: 3 3 5 8 9 9 |

四、解题思路

1. 核心思想

暴力枚举所有可能的子数组和 + 贪心选取:

  1. 枚举每一个可能的子数组和 target
  2. 对每个 target,用贪心算法 从左到右选出最多的不重叠子数组
  3. 遍历所有 target 后,保留最大数量

2. 问题本质分析

这是一个最优选择问题:

  • 条件:选出若干不重叠 子数组,所有子数组和必须相同
  • 目标:子数组数量尽可能多 本质是:尝试所有可能的和 → 对每个和计算最多能选多少个 → 取最大值。

3. 核心逻辑

  1. 枚举目标和 target:从 -1000 万 到 1000 万,覆盖所有可能出现的子数组和
  2. 贪心查找 :对每个 target,从左到右遍历 ,一旦找到和为 target 的子数组就立刻选中 ,然后从下一个位置继续找,保证不重叠 且数量最多
  3. 记录最大值 :遍历所有 target,保留能选出的最大子数组数量

4. 步骤拆解

  1. 输入读取

    • 读取数组长度 n 和数组元素
  2. 枚举目标和

    • 遍历所有可能的子数组和 target(-1000 万~1000 万)
  3. 贪心计算当前 target 能选多少个

    • 从左到右找和为 target 的子数组
    • 找到就计数,且跳过已选区域保证不重叠
    • 找不到就后移一位继续
  4. 更新最优解

    • 记录所有 target 中能选出的最大数量
  5. 输出结果

    • 输出最大数量

五、代码实现

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }

        int maxCount = 0;

        // 枚举所有可能的区间和
        for (int target = -10000000; target <= 10000000; target++) {
            int count = 0;
            int pos = 0;

            // 贪心:从左到右选不重叠的和为 target 的子数组
            while (pos < n) {
                int sum = 0;
                boolean found = false;
                for (int j = pos; j < n; j++) {
                    sum += a[j];
                    if (sum == target) {
                        count++;
                        pos = j + 1;
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    pos++;
                }
            }

            if (count > maxCount) {
                maxCount = count;
            }
        }

        System.out.println(maxCount);
    }
}
相关推荐
mmmmath_36 小时前
二叉树の递归遍历
算法
All for pursuit.7 小时前
【位运算-1】338.比特位计数
数据结构·c++·算法·leetcode
我可能是个假开发7 小时前
FTP Unicode 文件名导致 `550` 的问题分析与解决方案
java·开发语言·spring
caoerzhong7 小时前
中小企业上 WMS 该先上哪几块:JeeWMS 开源 Java 仓库管理系统的分批上线清单
java·python·开源
小师兄吃牛肉7 小时前
C语言中的nullptr有必要吗
c语言·c++·算法
【JAVA】玩家8 小时前
Spring核心原理全解析:从零到生产实战
java·后端·spring
Wang's Blog8 小时前
Java框架 SpringCloud 快速入门: 实现 Feign 最佳实践(抽取方式)
java·spring cloud
一只小小的芙厨9 小时前
【线性DP】
学习·算法·动态规划
xxwl5859 小时前
数据结构知识点和代码实现总结(C语言实现)
c语言·开发语言·数据结构
MandalaO_O9 小时前
IDEA 开发(快捷键 + 调试 + 序列化)
java·ide·intellij-idea