动态规划-线性dp

首先感谢y总:AcWing
如有侵权,请私聊,必删!
现在还没有理解线性dp的真正含义,先插个眼,后面补充


前言

本篇主要是作者学习线性dp的一些心得记录,如果有错误的地方,多谢指正!


一、线性dp是什么?

线性dp往往指在一个序列上进行的dp,当然也可能有两个甚至多个序列。一般来讲,线性dp的三个步骤分别有以下特点:

  1. 设计状态:至少有一维表示当前考虑的对象在数列上的位置。
  2. 状态转移:必须找到这条线上前面的位置的dp值来推出当前位置的dp值。
  3. 边界条件:第一个位置单独讨论。

二、相关题目

1.数字三角形

题目:

Acwing898

代码:

import java.io.*;

public class Main {
    private static int res;
    private static int n, m, t, k, r, l, a, b, c, x, y;
    private static String[] arrTemp;
    private static final int N = 510;
    private static int[][] q = new int[N][N];
    private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    private static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        n = Integer.parseInt(in.readLine());

        for (int i = 1; i <= n; i++) {
            arrTemp = in.readLine().split(" ");
            for (int j = 1; j <= i; j++)
                q[i][j] = Integer.parseInt(arrTemp[j - 1]);
        }

        for (int i = n - 1; i >= 1; i--)
            for (int j = 1; j <= i; j++)
                q[i][j] = Math.max(q[i + 1][j], q[i + 1][j + 1]) + q[i][j];

        out.write(q[1][1]+"");

        in.close();
        out.close();
    }
}

思路:q[i][j] = Math.max(q[i + 1][j], q[i + 1][j + 1]) + q[i][j];

对线性dp理解不大

2.摘花生

题目:

1015. 摘花生
1015. 摘花生

代码:

import java.io.*;

public class Main {
    private static int res;
    private static int n, m, t, k, r, l, a, b, c, x;
    private static String[] arrTemp;
    private static final int N = 110;
    private static int[][] g = new int[N][N];
    private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    private static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        int T = Integer.parseInt(in.readLine());

        while (T-- > 0) {

            arrTemp = in.readLine().split(" ");
            r = Integer.parseInt(arrTemp[0]);
            c = Integer.parseInt(arrTemp[1]);

            for (int i = 1; i <= r; i++) {
                arrTemp = in.readLine().split(" ");
                for (int j = 1; j <= c; j++)
                    g[i][j] = Integer.parseInt(arrTemp[j - 1]);
            }

            for (int i = 1; i <= r; i++)
                for (int j = 1; j <= c; j++)
                    g[i][j] += Math.max(g[i - 1][j], g[i][j - 1]);

            out.write(g[r][c] + "");
            out.newLine();
        }

        in.close();
        out.close();
    }
}

思路:g[i][j] += Math.max(g[i - 1][j], g[i][j - 1]);

心得:

没啥心得

3.最低通行费

题目:

1018. 最低通行费
1018. 最低通行费

代码:

import java.io.*;

public class Main {
    private static int res;
    private static int n, m, t, k, r, l, a, b, c, x, y;
    private static String[] arrTemp;
    private static final int N = 110;
    private static int[][] g = new int[N][N];
    private static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    private static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {

        n = Integer.parseInt(in.readLine());

        for (int i = 1; i <= n; i++) {
            arrTemp = in.readLine().split(" ");
            for (int j = 1; j <= n; j++)
                g[i][j] = Integer.parseInt(arrTemp[j - 1]);
        }

        // 初始化第一行和第一列的数据
        for (int i = 1; i <= n; i++) {
            g[i][1] += g[i - 1][1];
            g[1][i] += g[1][i - 1];
        }

        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                g[i][j] += Math.min(g[i - 1][j], g[i][j - 1]);

        out.write(g[n][n] + "");

        in.close();
        out.close();
    }
}

思路:g[i][j] += Math.min(g[i - 1][j], g[i][j - 1]);

注意初始化第一行和第一列的数据, 因为静态变量默认为0,数据范围0~100,取min会取0

心得:

x.xxxx

题目:

代码:

在这里插入代码片

思路:

心得:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值