01背包问题:双重约束

问题描述

玩家小豆是一位魔兽世界玩家,里面装备装备有装备等级的概念,装备等级越高的角色越厉害,现在小豆手中有n个金币,但身上最多穿着m件装备,每件装备的对应的价格x金币,对应的装备等级是y。现在小豆想要用手中的金币买到装备等级最大的装备组合。问小豆能买到最大的装备等级。

输入描述

金币数量n
最多穿装备的数量m
价格x,装备等级y

输出描述

能买到的装备等级加和

样例输入

130
3
100 380
20 320
40 360
50 310

样例输出

990


解题思路

很显然,这道题就是典型的背包问题,只不过它有两个约束条件,一个是手中金币数量n,即背包容量,另一个是最多穿着m件,即数量约束。

状态转移方程

首先我们先给出单约束背包问题的状态转移方程
State(i,j)= \begin{cases} State(i-1,j) ,if (w[i] \gt j) ①\\ max(State(i-1,j-w[i])+v[i],State(i-1,j)),if(w[i] \le j)②\\ \end{cases}
其中 :

  • State(i,j)表示,对于可选择的前i个物品,当背包容量是j时,所有选择中的最大价值。
  • w[i] 表示,第i个物品的重量(weight)
  • v[i] 表示,第i个物品的价值(value)

对于①式:该式表明,当第i个物品的重量大于背包容量时,该物品无法装进背包。则对于可选择的前i个物品与可选择的前i-1个物品,他们的最佳利益选择方式相同,最佳利益值也相同。

对于②式:该式表明,当第i个物品可以装进背包时,有两种选择。

  1. 装进背包,在这个条件下,所选方案的最大利益是 State(i-1,j-w[i]) + v[i]State(i-1,j-w[i])表示当背包容量为j-w[i]时,对于可选择的前i-1个物品的最大利益。
  2. 不装进背包,在这个条件下,所选方案的最大利益与 State(i-1,j)相同。

通过比较这两个情况来选择更优的那一方。


有了单约束背包问题的状态方程后,就便于我们理解双约束背包问题的状态方程。
State(i,j,k)= \begin{cases} State(i-1,j,k) ,if (w[i] \gt j) ①\\ max(State(i-1,j-w[i],k-1)+v[i],State(i-1,j,k)),if(w[i] \le j)②\\ \end{cases}
其中:

  • State(i,j,k)表示,对于可选择的前i个物品,当背包容量是j,背包可容纳件数是k时,所有选择中的最大价值。
  • w[i] 表示,第i个物品的重量(weight)
  • v[i] 表示,第i个物品的价值(value)

对于①式:该式表明,当第i个物品的重量大于背包容量时,该物品无法装进背包。则对于可选择的前i个物品与可选择的前i-1个物品,他们的最佳利益选择方式相同,最佳利益值也相同。

对于②式:该式表明,当第i个物品可以装进背包时,有两种选择。

  1. 装进背包,在这个条件下,所选方案的最大利益是 State(i-1,j-w[i],k-1) + v[i]State(i-1,j-w[i],k-1)表示当背包容量为j-w[i]且可容纳件数为k-1时,对于可选择的前i-1个物品的最大利益。
  2. 不装进背包,在这个条件下,所选方案的最大利益与 State(i-1,j,k)相同。

通过比较这两个情况来选择更优的那一方。

如果你理解到这里,那么对于更多重约束的背包问题,也已经可以写出状态转移方程了。

边界条件

State(0,j,k)=0
State(i,0,k)=0
State(i,j,0)=0

python实现

def get_input():
    n = 130
    m = 3
    eq_list = [(100, 380), (20, 320), (40, 360), (50, 310)]
    return n, m, eq_list

def main():
    # get the input
    n, m, eq_list = get_input()
    # define the state matrix, for fast performance. And the boundary conditions are initialized.
    # state[len(eq_list) + 1][n + 1][m + 1]
    state = [[[0 for _ in range(m + 1)] for _ in range(n + 1)] for _ in range(len(eq_list) + 1)]

    for k in range(1, m + 1):
        for j in range(1, n + 1):
            for i in range(1, len(eq_list) + 1):
                # in here the ith item in eq_list is eq_list[i-1] because i is in [1,len(eq_list)+1]
                # the value which means the level of equipments here
                v = eq_list[i - 1][1]
                # the weight which means the price of equipments here
                w = eq_list[i - 1][0]
                if w > j: # the item cant be put in bag
                    state[i][j][k] = state[i-1][j][k]
                else:
                    state[i][j][k] = max(state[i-1][j][k], # the case that do not put the item into bag
                                         state[i-1][j-w][k-1] + v) # the case that put the item into bag

    # the maximum value of bag problem
    print(state[len(eq_list)][n][m])

if __name__ == '__main__':
    main()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 先是原文复制: P01: 01背包问题题目有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i...
    Buyun0阅读 470评论 0 0
  • 我在进行一些互联网公司的技术笔试的时候,对于我来说最大的难题莫过于最后的那几道编程题了,这对算法和数据结构有一定程...
    柠檬乌冬面阅读 19,849评论 2 19
  • 来吧我们紧紧抓住青春的尾巴 回想当年曾貌美如花 岁月像极了荒芜的藤蔓 最难寻觅的是那青涩的枝桠 好吧再试着抓住青春...
    封狼居胥阅读 460评论 2 5
  • 你是想要什么味道的奶茶啊,你要哪个颜色的箱子啊,你是想买这只笔还是那只啊,你到底要哪一双鞋啊…… 你可以简单地把我...
    李子桃阅读 1,074评论 0 2
  • 不知道有没有和我一样喜欢酸奶的?我每天必须喝一桶酸奶。每次逛超市不由得就会留意奶制品区,开心的选一种酸奶...
    溱潇阅读 380评论 10 0