Gemini永久会员 Java动态规划

Java动态规划概述

动态规划(Dynamic Programming, DP)是一种解决复杂问题的算法思想,它将问题分解为子问题,通过存储子问题的解来避免重复计算,从而提高效率。在Java中实现动态规划通常涉及以下几种方式:

动态规划的基本实现方式

1. 自顶向下(记忆化递归)

java 复制代码
import java.util.Arrays;

public class MemoizationExample {
    private int[] memo;
    
    public int fibonacci(int n) {
        memo = new int[n + 1];
        Arrays.fill(memo, -1);
        return fibHelper(n);
    }
    
    private int fibHelper(int n) {
        if (n <= 1) return n;
        if (memo[n] != -1) return memo[n];
        memo[n] = fibHelper(n - 1) + fibHelper(n - 2);
        return memo[n];
    }
}

2. 自底向上(迭代法)

java 复制代码
public class BottomUpExample {
    public int fibonacci(int n) {
        if (n <= 1) return n;
        
        int[] dp = new int[n + 1];
        dp[0] = 0;
        dp[1] = 1;
        
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        
        return dp[n];
    }
}

经典动态规划问题示例

1. 0-1背包问题

java 复制代码
public class Knapsack {
    public int knapsack(int W, int[] wt, int[] val, int n) {
        int[][] dp = new int[n + 1][W + 1];
        
        for (int i = 0; i <= n; i++) {
            for (int w = 0; w <= W; w++) {
                if (i == 0 || w == 0) {
                    dp[i][w] = 0;
                } else if (wt[i - 1] <= w) {
                    dp[i][w] = Math.max(val[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i - 1][w]);
                } else {
                    dp[i][w] = dp[i - 1][w];
                }
            }
        }
        
        return dp[n][W];
    }
}

2. 最长公共子序列

java 复制代码
public class LCS {
    public int longestCommonSubsequence(String text1, String text2) {
        int m = text1.length(), n = text2.length();
        int[][] dp = new int[m + 1][n + 1];
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                }
            }
        }
        
        return dp[m][n];
    }
}

3. 硬币找零问题

java 复制代码
import java.util.Arrays;

public class CoinChange {
    public int coinChange(int[] coins, int amount) {
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, amount + 1);
        dp[0] = 0;
        
        for (int i = 1; i <= amount; i++) {
            for (int coin : coins) {
                if (coin <= i) {
                    dp[i] = Math.min(dp[i], dp[i - coin] + 1);
                }
            }
        }
        
        return dp[amount] > amount ? -1 : dp[amount];
    }
}

动态规划四要素

  1. 状态定义:明确DP数组或变量表示什么
  2. 状态转移方程:找出如何从子问题推导出当前问题的解
  3. 初始条件:确定基础情况的解
  4. 计算顺序:确定是自顶向下还是自底向上

优化技巧

  1. 空间优化:对于某些问题,可以使用滚动数组减少空间复杂度
  2. 状态压缩:当状态转移只依赖前几个状态时,可以只保存这些状态
  3. 提前终止:在某些情况下可以提前终止计算

动态规划是解决许多经典问题(如最短路径、资源分配、序列比对等)的强大工具,掌握它需要大量的练习和模式识别。

相关推荐
abcnull4 小时前
用javaparser做精准测试
java·ast·静态代码分析·精准测试·javaparser
叶小鸡4 小时前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题】【Java基础篇】第22题:HashMap 和 HashSet 有哪些区别
java·开发语言·哈希算法·散列表·hash
juniperhan4 小时前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054734 小时前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
c++之路5 小时前
C++23概述
java·c++·c++23
专注API从业者6 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠6 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY6 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
切糕师学AI7 小时前
环形缓冲区(Ring Buffer / Circular Buffer)详解:原理、优势、应用与高性能实现
数据结构·环形缓冲区