背包问题

作者: jianpengma | 来源:发表于2018-11-22 15:31 被阅读0次

假设有n件物品,每件物品都有各自的重量和价值,现在给一个最多可以装v重量的背包,请问如何装才能使价值最大。

用动态规划,状态转移方程是:

v[i][j]=max(v[i-1][j], v[i-1][j-goods[i-1].weight] + goods[i-1].value)

v是一个二维数组,行代表第几件物品,列代表背包容量,第一行和第一列的所有值都是0。v[i][j]代表第i件物品,在volumn是j的时候,可以放的最大价值。

goods[i-1],代表的是goods数组里的第i件物品,因为下标是从0开始的。

#include <iostream>

using namespace std;

const int N = 10;

struct goods{

    int idx;

    int weight;

    int value;

};

//struct good goods[N];

struct goods goodss[5] = {{1,2,6},

                    {2,2,3},

                    {3,6,5},

                    {4,5,4},

                    {5,4,6}};

int KnapSack(int n,struct goods goodss[],int volumn){

    int V[N][10*N]; //初始化10行100列的数组

    for(int i = 0; i <= n; i++)//初始化第0列

        V[i][0] = 0;

    for(int j = 0; j <= volumn; j++)//初始化第0行

        V[0][j] = 0;

    for(int j = 0; j <= volumn; j++)

        cout<<V[0][j]<<" ";

    cout<<endl;

    for(int i = 1; i <= n; i++) // 迭代物品

    {

        for(int j = 1; j <= volumn; j++)  // 对于每个重量进行处理

            if(j < goodss[i-1].weight)

                V[i][j] = V[i-1][j];  // 当前物品的重量大于背包重量,用前一个物品的当前volumn的结果

            else

                V[i][j] = max(V[i-1][j],V[i-1][j-goodss[i-1].weight] + goodss[i-1].value); //当前goods的下标是[i-1]

        for(int j = 0; j <= volumn; j++)

            cout<<V[i][j]<<" ";

        cout<<endl;

    }

    return V[n][volumn];

}

int main()

{

    int n=5;

    int volumn=10;

    int sum = KnapSack(n,goodss,volumn);

    cout<<"sum is "<<sum<<endl;

    return 1;

}

leetcode上的coin change,要求的是用最少的硬币,组成一个特定值

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

经典的动态规划题

注意点:  一开始先初始化一维数组的内容为比总额大1,同时大小是总额+1,因为数组下标是从0开始,要使数组最后一个元素是总额,总大小是总额+1

m*n的时间复杂度

只有 coin <= i: 才能做方程

class Solution(object):

    def coinChange(self, coins, amount):

        """

        Very classic dynamic programming problem, like 0-1 Knapsack problem.

        dp[i] is the fewest number of coins making up amount i,

        then for every coin in coins, dp[i] = min(dp[i - coin] + 1).

        """

        dp = [amount + 1] * (amount + 1) # construct a list with (amount+1) elements, each element value is (amount+1)

        dp[0] = 0

        #for i in range(amount + 1):

        for coin in coins:

            for i in range(1, amount + 1):

                if coin <= i:

                    dp[i] = min(dp[i], dp[i - coin] + 1)

        return -1 if dp[amount] > amount else dp[amount]

对于{2,3,5}的coin,总价值是10,输出矩阵应该是:

0 0  1   2    3  4   5   6   7   8   9 10

2 0, 11, 1, 11, 2, 11, 3, 11, 4, 11, 5

3 0, 11, 1,  1,  2,  2,  2,  3,  3,  3, 4

5 0, 11, 1,  1,  2,  1,  2,  2,  2,  3,  2

相关文章

  • 背包问题(完全背包)

    动态规划合集: 1.矩阵链乘法2.投资组合问题3.完全背包问题4.01背包问题5.最长公共子序列 例题3——背包问...

  • Algorithm进阶计划 -- 动态规划(下)

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • 背包问题

    0-1背包问题 问题 n个物体,它们各自有重量和价值,给定一个有容量的背包,如何让背包里装入的物体价值总和最大? ...

  • 背包问题

    问题描述 假如有一个能装下4磅的背包,如何从下列商品列表中选择商品填充背包,使价值达到最大: 动态规划 要解决背包...

  • 背包问题

    (1)0-1背包容量为10的背包,有5种物品,每种物品只有一个,其重量分别为5,4,3,2,1,其价值分别为1,2...

  • 背包问题

  • 背包问题

    01背包(物品只有一个) 有N件物品和一个容量为V的背包。第i建物品的费用是w[i],价值是v[i]。求解将哪些物...

  • 背包问题

    1. 01背包 状态说明:背包体积为v,物品个数为n,f[n,v]表示前n件物品加入背包的最大价值。c_i,w_i...

  • 背包问题

    01背包 优化空间复杂度,变为一维; 外循环依然是n从1->N, 注意内循环 v是从V->0,为什么内循环是V->...

  • 背包问题

    介绍 学习动态规划算法的经典例题。动态规划算法一般有3个特征1、最优化原理:最优解所包含的子问题的解也是最优的。2...

网友评论

    本文标题:背包问题

    本文链接:https://www.haomeiwen.com/subject/iamifqtx.html