蓝桥杯21241灯塔java

本题是一个经典的线性动态规划问题。

首先,我们需要分析题目中的核心约束:"如果灯塔 ai​−1 或ai​+1 已经被点亮,则灯塔 ai​ 无法被点亮"。这意味着我们选出的灯塔集合中,任意两个灯塔的编号不能相邻

题目提到可以挑选一个"子序列",这实际上是一个提示:只要我们选出的灯塔编号集合满足"互不相邻"的条件,我们总能找到一种操作顺序(例如按照编号从小到大,或者隔开操作),使得这些灯塔全部被成功点亮。因此,问题转化为:在给定的可用编号集合中,选出最多的元素,使得任意两个元素值不相邻(即不连续)。

我们建立动态规划状态:

定义 dpi表示:在只考虑编号为 1 到 i 的灯塔的情况下,最多能点亮的灯塔数量。

我们考虑如何转移:

对于第 i 号灯塔,我们有两种决策情况:

  1. 不点亮第 i 号灯塔(或者第 i号灯塔根本不在给定的输入序列 a 中): 此时,最大数量直接继承自前一个状态dpi−1

    dpi=dpi−1

  2. 尝试点亮第 i号灯塔(前提是输入序列 a 中包含 i): 如果我们要点亮 i,那么根据约束,我们绝对不能点亮 i−1。因此,我们的收益是"1 到i−2 的最大值"加上当前这 1 个。

    dpi=max⁡(dpi−1,dpi−2+1)

为了优化空间,观察到计算 dpidpi 只需要 dpi−1dpi−1 和 dpi−2dpi−2 两个状态,我们可以使用滚动变量

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Set;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] nm = br.readLine().split(" ");
        int n = Integer.parseInt(nm[0]);
        int m = Integer.parseInt(nm[1]);
        String[] arr = br.readLine().split(" ");

        // 标记哪些编号在序列中出现过
        Set<Integer> exist = new HashSet<>();
        for(String s : arr){
            exist.add(Integer.parseInt(s));
        }

        // 滚动变量:pre2=dp[i-2], pre1=dp[i-1], cur=dp[i]
        int pre2 = 0; // dp[0]=0
        int pre1 = exist.contains(1) ? 1 : 0; // dp[1]
        int ans = pre1;

        for(int i = 2; i <= n; i++){
            int cur;
            if(!exist.contains(i)){
                cur = pre1; // 不能选i,继承dp[i-1]
            }else{
                cur = Math.max(pre1, pre2 + 1); // 选/不选取最大
            }
            pre2 = pre1;
            pre1 = cur;
            ans = cur;
        }
        System.out.println(ans);
    }
}
相关推荐
大熊背3 小时前
《Color constancy by characterization of illumination chromaticity》之色度色域最大化算法(二)
算法·白平衡·色度·色温
香菜TTT4 小时前
大模型上下文协议(MCP):AI 应用的“USB-C”接口技术
开发语言·人工智能·经验分享
钓鱼的肝4 小时前
梳理(1-5)
c++·经验分享·笔记·算法·青少年编程
aramae4 小时前
模拟实现strlen()函数 (C语言)
c语言·开发语言·后端
HZZD_HZZD4 小时前
CSDN_批发市场水电漏损归因算法LAM的原理与落地
嵌入式硬件·物联网·算法
SL_staff4 小时前
别急着买商业规则引擎:90%风控场景根本不需要全量编码能力
java·程序员·groovy
ManageEngineITSM5 小时前
DevOps和ITIL是什么关系?是替代还是互补一文讲清
java·服务器·资产管理·变更管理
jimy15 小时前
readelf 查看“派生类”的vtable符号
开发语言·c++
SL_staff5 小时前
ERP排程总在纸上谈兵?JVS-APS如何用真实产能约束打通计划与执行闭环
java·人工智能·开源
xcl09255 小时前
24小时自助健身房系统软件开发实战指南:从架构到部署
java·spring boot