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

一、题目描述

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

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

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

二、输入输出描述

输入描述

  • 第一行:数组长度 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);
    }
}
相关推荐
tycooncool2 小时前
Spring中的IOC详解
java·后端·spring
014-code2 小时前
日志规范:怎么写才不算写废话
java·开发语言·设计模式·日志
一江寒逸2 小时前
零基础从入门到精通 AI Agent 开发(全栈保姆级教程)附加篇:AI Agent 面试八股文全集
人工智能·面试·职场和发展
爱敲代码的小黄2 小时前
我重新梳理了一遍 RAG,终于明白它不只是接个向量库
后端·面试·agent
CQU_JIAKE2 小时前
4.17[Q]
java·linux·服务器
久菜盒子工作室3 小时前
面试经验|产品经理|自我介绍
面试·职场和发展·产品经理
cpp_25013 小时前
P2347 [NOIP 1996 提高组] 砝码称重
数据结构·c++·算法·题解·洛谷·noip·背包dp
Hugh-Yu-1301233 小时前
二元一次方程组求解器c++代码
开发语言·c++·算法
Ruihong3 小时前
Vue v-bind 转 React:VuReact 怎么处理?
vue.js·react.js·面试