动态规划讲解及应用

动态规划

 

动态规划算法介绍

@author:qyx      2013/6/5

1)  动态规划的核心思想:将大问题划分为小问题进行解决,从而一步步获取最优解的处理算法

2)  动态规划尽管与分治算法极其类似,但也有不同,与分治算法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段解的基础上,进行进一步求解)

3)  动态规划可以通过填表的方法来逐步推进,得到最优解

动态规划实例:

使用动态规划解决背包问题(01背包)

思路分析

背包问题主要是指一个给定容量的背包,若干具有一定价值和重量的物品,如何选择物品放入背包使物品的价值最大。其中又分01背包和完全背包(完全背包指的是:每种物品都有无限件可用)

这里的问题属于01背包,即每个物品最多放一个,而完全背包可以转化为01背包

 

package com.qyx.Tree;

public class KnapsackProblem {
    public static void main(String[] args) {
        int[]w={1,4,3};//物品重量
        int[]val={1500,3000,2000};//物品价值
        int m=4;//背包容量
        int n=val.length;//物品个数
        //创建二维数组
        //v[i][j]表示在前i个物品中能够装入容量为j的背包中的最大价值 
        int[][] v=new int[n+1][m+1];
        //记录放商品的情况
        int[][] path=new int[n+1][m+1];
        //初始化第一行第一列,这里可以不用设置,默认就是0
        for(int i=0;i<v.length;i++)
        {
            v[i][0]=0;
        }
        for(int j=0;j<v[0].length;j++)
        {
            v[0][j]=0;
        }
        //根据公式进行动态规划处理
        for(int i=1;i<v.length;i++)
        {
            for(int j=1;j<v[0].length;j++)
            {
                //公式
                if(w[i-1]>j) //因为i从1开始,所以w[i]要变为w[i-1]
                {
                    v[i][j]=v[i-1][j];
                }else{
                    //v[i][j]=Math.max(v[i-1][j], val[i-1]+v[i-1][j-w[i-1]]); //因为i从1开始,因此公式需要调整
                    if(v[i-1][j]<val[i-1]+v[i-1][j-w[i-1]])
                    {
                        v[i][j]=val[i-1]+v[i-1][j-w[i-1]];
                        //记录当前的情况
                        path[i][j]=1;
                    }else{
                        v[i][j]=v[i-1][j];
                    }
                }
            }
        }
        int i=path.length-1;
        int j=path[0].length-1;
        while(i>0&&j>0)
        {
            if(path[i][j]==1)
            {
                System.out.println("第"+i+"个商品放入到背包");
                j-=w[i-1];
            }
            i--;
        }
    }
}
原文地址:https://www.cnblogs.com/qyx66/p/12310253.html