动态规划基础---类背包问题.

284 阅读2分钟

前言

最近发现动态规划这类问题有很多,我也是去了解了一下,我个人感觉这类算法很难,

所以今天小编就简单介绍一下动态规划的最经典问题---背包问题

动态规化:

这类算法的题目相信学过贪心算法的同学总感觉可以用贪心做,但是想不出怎么去实现. 其实呢,贪心能做,用暴力枚举但是时间复杂度是o(n^3)以上.显然效率是很低的. 所有我们可以用动态规划去优化算法>

2.状态规划的核心就是状态的转移,首先要想想怎么转移,再去构造状态转移方程

例题

选自洛谷题号p1048

屏幕截图 2023-11-07 165257.png

第一眼这题很想背包问题,看完发现这就是背包问题换了一下背景.那么我们该怎么去分析呢?

1.这里的状态其实就是背包的剩余空间 那么我们可以,而要就价值的最大,要比较前后的状态大小; 状态转移方程为

dp[i][j]=Math.max(dp[i-1][j-w[i]]+val[i],dp[i-1][j]);

这里看起来像是递归的用法.为的就是转换每一次的转态,dp[][]每一个都有值,只是不容易看出,仔细分析是不是每一次获取都要上一次获取的状态进行比较.但是如果背包容量不够呢 那么可以直接获取上一次转态,就不用进行比较了.

最后我们进行代码实现

public static void main(String[] args) {
    Scanner sc=new Scanner(System.in);
    int []w=new int[105];
    int []val=new int[105];
    int [][]dp=new int[105][105];//状态转移量
    int t,m,res;//定义T表示时间,m为数量
    t=sc.nextInt();
    m=sc.nextInt();
    for (int i =1; i <=m; i++) {
        w[i]=sc.nextInt();
        val[i]=sc.nextInt();
    }
    for (int i = 1; i <= m; i++) {
        for(int j=t;j>=0;j--){
            if(j>=w[i]){
                dp[i][j]=Math.max(dp[i-1][j-w[i]]+val[i],dp[i-1][j]);
            }else {
                dp[i][j]=dp[i-1][j];
            }
        }


    }
    System.out.println(dp[m][t]);
}

那么这就是这题的解析了,但是时间复杂度还是 o(mt),那么有没有更加厉害的方法呢?

目前小编还在学习,还不知道,等小编学成归来再来分享吧. 会的小伙伴也可以在评论区分享哦