/**
* 背包问题关于动态规划的思想进行操作的
*/
public class PackageProtect {
public static void main(String[] args) {
/**
* 35,30,60,50,40,10,25
* 10,40,30,50,35,40,30
*/
int []weight=new int[]{35,30,60,50,40,10,25};
int []value=new int[]{10,40,30,50,35,40,30};
int capcity=150;
System.out.println(getMaxCount(capcity, weight, value));
}
private static int getMaxCount(int capcity, int[] weight, int[] value) {
int max=0;
/**
* 可以用一个状态转移方程来解决
* dp[i][j],表示将前i件物品,装进限重为j的背包,可以获得的最大价值。
* 0<=i<=N, 0<=j<=W
* 此时,需要进行写出状态转移方程
* dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]+v[i]);dp[i][j]使用来计算最大价值的
* 因此,在这个地方
* 若如果从中减去一个物品i,那么解中剩下的物品,
* 一定是“用除i外的所有N-1件物品,放入容量为W-w[i]的背包中”的最优解。
* 因此,利用到状态转移的方程的进行计算
*dp[i][j]有两种情况:
* 不装入第i件物品,即dp[i−1][j];
* 装入第i件物品(前提是能装下),即dp[i−1][j−w[i]] + v[i]。
*
*
*/
int n=weight.length;
int [][]dp=new int[n+1][capcity+1];
for (int i = 1 ; i <=n ; i++) {
for (int j=0;j<=capcity;j++){
if(j>=weight[i-1]){
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-weight[i-1]]+value[i-1]);
}else {
dp[i][j]=dp[i-1][j];
}
}
}
max=dp[n][capcity];
return max;
}
}
动态规划的核心思想:
动态规划过程是:把原问题划分成多个“阶段”,依次来做“决策”,得到当前的局部解;每次决策,会依赖于当前“状态”,而且会随即引起状态的转移。
这样,一个决策序列就是在变化的状态中,“动态”产生出来的,这种多阶段的、最优化决策,解决问题的过程就称为动态规划(Dynamic Programming,DP)。
动态规划的设计都有着一定的模式,一般要经历以下几个步骤。
(1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。
(2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。
(3)确定决策,并写出状态转移方程
因为决策和状态转移有着天然的联系,状态转移就是:根据上一阶段的状态和决策,来导出本阶段的状态。
(4)寻找边界条件
给出的状态转移方程一般是一个递推式,需要一个递推的终止条件或边界条件。
一般,只要解决问题的阶段、状态和状态转移决策确定了,就可以写出状态转移方程。
实际应用中可以按以下几个简化的步骤进行设计:
(1)分析最优解的性质,并刻画其结构特征
(2)递归的定义最优解
(3)以自底向上或自顶向下的记忆化方式(备忘录法)计算出最优值
(4)根据计算最优值时得到的信息,构造问题的最优解