线性DP

LeetCode 300. 最长递增子序列

LeetCode674. 最长连续递增序列

题解:最长上升子串模板题

定义fi表示以i结尾的最长上升子串

nums[i-1] < nums[i],则有f[i] = f[i-1] + 1
nums[i-1] > nums[i],则有f[i] = 1

public class Solution {
    public int findLengthOfLCIS(int[] nums) {
        int n = nums.length;
        int[] f = new int[n];
        Arrays.fill(f, 1);
        int res = 1;
        for(int i = 0; i < n; i++) {
            if(i > 0 && nums[i] > nums[i-1]) f[i] = f[i-1] + 1;
            res = Math.max(res, f[i]);
        }
        return res;
    }
}

携程2023030701

题目内容

定义一个数组为“稳定的”,当且仅当数组中相邻的两个元素之差的绝对值不超过1。

例如:

  • 数组 [2, 3, 2, 2, 1] 是稳定的,因为相邻元素之差不超过1。
  • 数组 [1, 3, 2] 不是稳定的,因为1和3之间的差的绝对值超过了1。

给定一个由 n 个整数组成的数组 a,求该数组的最长的稳定的连续子数组的长度。

输入描述

第一行输入一个正整数 n,代表数组的大小。

第二行输入 n 个正整数 ai,代表数组的元素。

1 ≤ n ≤ 100000,1 ≤ ai ≤ 10^9

输出描述

一个正整数,代表最长连续稳定子数组的长度。

样例

输入

6
2 3 5 4 5 6

输出

4

思路

likou674. 最长连续递增序列差不多。
f[i] 为以 i 结尾的稳定子数组的长度。

f[i] 初始值为 1,如果它与它左侧的元素 nums[i-1] 的差值 diff = abs(nums[i] - nums[i-1]) 满足 diff ≤ 1,则有 f[i] = f[i-1] + 1

`import java.util.*;

public class Main {
static final int N = 100010;
static int n, a[] = new int[N], f[] = new int[N];

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    n = sc.nextInt();
    for (int i = 0; i < n; i++) {
        a[i] = sc.nextInt();
    }
    int res = 1;
    f[0] = 1;
    for (int i = 1; i < n; i++) {
        if (Math.abs(a[i] - a[i - 1]) <= 1) {
            f[i] = f[i - 1] + 1;
        } else {
            f[i] = 1;
        }
        res = Math.max(res, f[i]);
    }
    System.out.println(res);
}

}`

科大讯飞2022101001

输入:

第一行字符串表示赛道X的奖金编号。
第二行字符串表示赛道Y的奖金编号。
编号范围为a-z和0-9,赛道关卡数为1-100。

输出:

两兄弟最多可获得的奖金数。

示例:

输入:

1323467
1378694

输出:

4

说明:
如赛道X和Y中获得奖金1和6,不连续,获得2份奖金;
如获得奖金1和3,连续,获得4份奖金。

思路:
这道题和力扣718.最长连续子数组一模一样

定义 f[i][j] 为以 nums1[i] 结尾和以 nums2[j] 结尾的最长公共子串

  • nums1[i] 不等于 nums2[j],则有 f[i][j] = 0
  • nums1[i] 等于 nums2[j],则有 f[i][j] = f[i-1][j-1] + 1
package com.coedes.dp.kedaxunfei20221010;

import java.util.Scanner;

/**
 * @author 17259
 * @create 2024-06-15 17:51
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String X = sc.nextLine();
        String Y = sc.nextLine();
        System.out.println(solve(X, Y));
    }

    private static int solve(String X, String Y) {
        int lenX = X.length();
        int lenY = Y.length();
        int[][] dp = new int[lenX + 1][lenY + 1];
        int res = 0;
        for (int i = 1; i <= lenX; i++) {
            for (int j = 1; j <= lenY; j++) {
                if (X.charAt(i - 1) == Y.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } 
                res = Math.max(dp[i][j],res);
            }
        }
        return res*2;
    }
}

20221013荣耀

在某个遥远国度里有一种传统的游戏叫做“跳跳棋”。游戏棋盘呈直线状,共有N格,起始位置和结束位置在棋盘之外。每格有不同的积分值,玩家每次跳跃必须跳过一个或多个格子,不允许跳到相邻格子或回跳。目标是通过跳跃获取最高积分。

输入描述:

  • 第一行是整数N,表示跳棋格数(1 ≤ N ≤ 100,000)
  • 第二行是N个整数,每个整数表示对应格子的积分值(1 ≤ M ≤ 1,000)

输出描述:

  • 能获得的最高积分

示例:
输入

3
1 5 2

输出

5

思路:
这和力扣198.打家劫舍 思路一样,
起始位置和结束位置在棋盘之外 且 (1 ≤ N ≤ 100,000) ,定义长度为 N+1 数组 ,起点为0

package com.coedes.dp.rongyao20221013;

import java.util.Scanner;

/**
 * @author 17259
 * @create 2024-06-16 10:44
 */
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N  = sc.nextInt();
        int[] M = new int[N+1];
        for (int i = 1; i <= N; i++) {
            M[i] = sc.nextInt();
        }
        System.out.println(solve(M));
    }

    private static long solve(int[] m) {
        int length = m.length;
        long[] dp = new long[length];
        dp[1] = m[1];
        for (int i = 2; i < length; i++) {
            dp[i] = Math.max(dp[i-1],dp[i-2]+m[i]);
        }
        return dp[length-1];
    }
}

2023081101 快手

一个整数数组中选出一些数,使得这些数的和尽可能大,但不允许选择相邻的元素。要求设计一个算法,在O(n)的时间复杂度内计算出答案。

输入描述:

  • 一行输入包含n个正整数,以EOF结尾。

输出描述:

  • 第一行输出选中的数在整数数组中的索引,空格隔开,以空格结束。
  • 第二行输出选中的数的和。

示例:
输入

1 6 2 7 3 8 4 9 5 10

输出

1 3 5 7 9 
40

思路:
打家劫舍 + 标记数组

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 17259
 * @create 2024-06-16 12:51
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String[] split = reader.readLine().split(" ");
        int n = split.length;
        long[] a = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            a[i] = Long.parseLong(split[i - 1]);
        }
        solve(a, n);
    }

    private static void solve(long[] a, int n) {
        long[] dp = new long[n + 1];
        boolean[] flag = new boolean[n + 1];
        dp[0] = 0;
        dp[1] = a[1];
        flag[1] = true;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1];
            long val = dp[i - 2] + a[i];
            if (val > dp[i]) {
                dp[i] = val;
                flag[i] = true;
            }
        }
        List<Integer> ans = new ArrayList<>();
        int cur = n;
        while (cur > 0) {
            if (flag[cur]) {
                ans.add(cur - 1);
                cur -= 2;
            } else {
                cur -= 1;
            }
        }
        for (int i = ans.size() - 1; i >= 0; --i) {
            System.out.print(ans.get(i) + " ");
        }
        System.out.println();
        System.out.println(dp[n]);
    }
}
posted @ 2024-06-17 11:27  菠萝包与冰美式  阅读(2)  评论(0编辑  收藏  举报