动态规划 01背包 java实现

import org.junit.Test;

/**
 * @auther qwh
 * @create 2022-11-19-14:48
 */
public class packge0_1 {
    /**
     * 使用二维数组非递归的方法求解0/1背包问题
     *01背包问题就是一个不断填表的过程
    */
        // N表示物体的个数,V表示背包的载重

        public int func(int weight[],int value[],int w)
        {
            int N=weight.length;//物体的个数
            int f[][]=new int[N+1][w+1];//列是物品的重量和价值,行是背包装的体积
            //当不放物品时
            for(int col=0;col<w+1;col++)
            {
                f[0][col]=0;
            }
            //当背包体积是0时
            for(int row=0;row<N+1;row++)
            {
                f[row][0]=0;
            }
            //其他的地方从第二行,第二列开始
            //一行一行填表
            for(int col=1;col<N+1;col++)//当前物品的重量weight[col-1] 当前物品的价值values[col-1]
            {
                for(int row=1;row<w+1;row++)//列代表背包当前容量
                {
                    //比较当前物品的重量能否加入背包
                    if(weight[col-1]<row)//yes
                    {
                        //比较不加入该物品时该重量的最大价值(前一行)与当前物品的价值+可以容纳的剩余重量的价值
                        //不加入当前物品的最优解为前一行f[col-1][row]
                        //加入当前物品后背包剩余的容量应该是剩余容量的最优解(在上一行)f[col-1][row-weight[col-1]]
                        f[col][row]=Max(f[col-1][row],value[col-1]+f[col-1][row-weight[col-1]]);
                    }
                    else//但前物品放不进就选当前容量的最优解即(上一行)
                    {
                        f[col][row]=f[col-1][row];
                    }
                }
            }
            for (int[] rows: f) {
                for (int col : rows) {
                    System.out.format("%5d",col);
                }
                System.out.println();
            }

            return f[N][w];
        }
        public int Max(int x,int y) {
            if (x >= y)
                return x;
            else
                return y;
        }
    @Test
    public void test(){
            int weight[]=new int[]{2,2,6,5,4};
            int value[] =new int[]{6,3,5,4,6};
            int w=10;
            System.out.println("最大价值为"+func(weight,value,w));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值