zoukankan      html  css  js  c++  java
  • 动态规划法求背包问题

    0-1背包问题是指给定一个容量一定的背包和一系列已知重量和价值的物品,从中选择一些物品放入背包使得背包中物品的总价值最大.

    背包问题可以用动态规划,回溯法或者贪心算法求解.这里介绍使用动态规划法求解0-1背包问题.

    动态规划法需要几个数组来辅助:

    • m: 背包最大容量

    • n: 物品的个数

    • w[i] : 第i个物品的重量

    • v[i]: 第i个物品的价值

    • c[i][j]: 前i个物品放入容量为j的背包最大的价值

    动态规划法的最终目的是填写二维数组c,c[n][m]即为原问题的结果.

    为了方便起见下标从1开始, i表示物品编号, j表示当前容量.先行后列,从上到下,从左到右填写二维数组c.

    • 若总容量小于物品质量(j < w[i]), 当前最大价值不变(c[i][j] = c[i-1][j])

    • 前i-1个物品选择装入第i个物品后正好装满的方案(c[i-1][j-w[i]]), 若装入后价值比前i-1个物品最大价值(c[i-1][j])更大,则装入第i个物品;

    • 否则保留前i-1个物品最大价值(c[i-1][j])

    上述三种状态下

    举一个简单的例子:

    背包最大容量为10,有三个物品重量和价值分别为: (3,4),(4,5), (5,6),求背包最大价值.

    填写二维数组c:

    0 0 4 4 4 4 4 4  4  4 
    0 0 4 5 5 5 9 9  9  9
    0 0 4 5 6 6 9 10 11 11 
    

    由此可知最大价值为11.

    一言不发就丢代码:

     #include <stdio.h>
    
    #define M 128
    #define N 32
    
    int m = 0, n = 0;
    int c[N][M] = {0};
    int w[N] = {0};
    int v[N] = {0};
    
    void npack() {
        int i, j;
        for (j=1; j <= m; j++) {
            for (i=1; i <= n; i++) {
                if (j < w[i]) {
                    c[i][j] = c[i-1][j];
                    continue;
                }
                else if(c[i-1][j-w[i]] + v[i] > c[i-1][j]) {
                    c[i][j] = c[i-1][j-w[i]] + v[i];
                }
                else {
                    c[i][j] = c[i-1][j];
                }
            }
        }
    }
    
    int main() {
        int i, j;
        // input
        scanf("%d %d", &m, &n);
        for (i = 1; i <= n; i++) {
            scanf("%d %d", &w[i], &v[i]);
        }
        npack();
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= m; j++) {
                printf("%4d ", c[i][j]);
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    JAVA合并两个有序的单链表,合并之后的链表依然有序
    excel如何将一个单元格内容拆分成多个单元格?(用到了数据->分列)
    Navicat导入excel的xlsx文件提示无法打开文件
    Request对象实现请求转发
    MessageFormat.format()和String.format()
    使用Servlet动态生成验证码
    Http协议
    使用freemarker导出word
    java注解学习(1)注解的作用和三个常用java内置注解
    SSM_CRUD新手练习(6)分页后台控制器编写
  • 原文地址:https://www.cnblogs.com/Finley/p/5474772.html
Copyright © 2011-2022 走看看