前言
最近发现动态规划这类问题有很多,我也是去了解了一下,我个人感觉这类算法很难,
所以今天小编就简单介绍一下动态规划的最经典问题---背包问题
动态规化:
这类算法的题目相信学过贪心算法的同学总感觉可以用贪心做,但是想不出怎么去实现. 其实呢,贪心能做,用暴力枚举但是时间复杂度是o(n^3)以上.显然效率是很低的. 所有我们可以用动态规划去优化算法>
2.状态规划的核心就是状态的转移,首先要想想怎么转移,再去构造状态转移方程
例题
选自洛谷题号p1048
第一眼这题很想背包问题,看完发现这就是背包问题换了一下背景.那么我们该怎么去分析呢?
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),那么有没有更加厉害的方法呢?
目前小编还在学习,还不知道,等小编学成归来再来分享吧. 会的小伙伴也可以在评论区分享哦