蓝桥杯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);
    }
}
相关推荐
wdfk_prog1 小时前
嵌入式面试真题第 11 题:RTOS 优先级翻转与实时任务阻塞的通用治理
c语言·缓存·面试·职场和发展·架构
这个DBA有点耶2 小时前
SQL调优进阶:从“优化一条SQL”到“优化一个系统”的思维升级
java·大数据·数据库·sql·程序人生·dba·改行学it
许彰午3 小时前
95_Python内存管理与垃圾回收
开发语言·python
csdn2015_3 小时前
springboot读取配置的方法
java·spring boot·spring
多加点辣也没关系3 小时前
JavaScript|第13章:原始类型的方法
开发语言·javascript·ecmascript
এ慕ོ冬℘゜3 小时前
深入理解 JavaScript 事件体系:Window、鼠标与键盘事件详解
开发语言·javascript·okhttp
AOwhisky3 小时前
下一代容器来了?Docker 宣布原生支持 WebAssembly
java·运维·docker·容器·rust·wasm
QXWZ_IA4 小时前
1库1图1批是什么?千寻位置公安地图数据体系详解
科技·算法·能源·媒体·交通物流·政务
c238564 小时前
Bug 猎手入门指南
c++·算法·bug