求助,一个比多重背包还要复杂一点的问题。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tmsdy0404
V2EX    问与答

求助,一个比多重背包还要复杂一点的问题。

  •   tmsdy0404 2022-03-19 11:41:09 +08:00 1470 次点击
    这是一个创建于 1389 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现有商品 N(N<100)类,第 i 类商品的数量为 C[i],单价为 P[i], 即第 i 类商品的总价格为 C[i]*P[i]。 则所有商品的总价格 PN 为:

    商品总价格

    另有发票 M(M<N)张。 第 k 张发票的金额为 V[k]。 所以发票的总金额 PM 为:

    发票总金额

    且 PM = PN 。

    求如何分配商品,使其总金额刚好对应上每一张发票金额。 (允许有正负 1 元的误差,我也觉得不可理解,但事实就是这样)

    ^^^^^^^^^^^^^^说人话的分割线^^^^^^^^^^^^^^^^^^^^^^^

    上面说的可能不太清楚,我直接举例: 样例

    绿色区域就是要求解的值。可能有很多解,只需要求出来使每个发票金额刚好满足就可以。

    个人感觉,如果把每一张发票金额去按多重背包问题求最优,不一定能保证所有发票整体最优。 另外,我这个价格也就是背包问题中的体积,是有小数的,难道要全部放大 100 倍来求解吗?

    tmsdy0404
        1
    tmsdy0404  
    OP
       2022-03-19 12:55:35 +08:00 via iPhone
    坐等大佬解惑~~~~
    wa007
        2
    wa007  
       2022-03-19 19:10:35 +08:00
    相比多重背包,你这个题目一共有 M 个背包,套用多重背包的做法开销实在太大了。
    这应该是个业务问题,不是个算法问题吧。
    wa007
        3
    wa007  
       2022-03-19 19:27:55 +08:00
    1. 初始化
    1 )把所有商品放入集合 A
    2 )把所有发票放入集合 B

    2. 迭代
    1 )调用多重背包算法,判断当前的集合 A 都可以组成和为哪些金额的发票,输出数组 A_array ,A_array[i] = True 表示 金额为 i 的发票可以由集合 A 中的某些商品求和得到,A_array[j] = False 表示金额 j 的发票不能由 A 中的商品求和得到。
    2 )从小到大遍历集合 B 中的发票,假设当前是金额为 i 的发票,判断 A_array[i] 如果是 True ,就把 i 从集合 B 中删除,同时加入 {j - i for j in B if j > i}(因为你下次可以组成金额为 j-i 的发票,然后把 j 删除,i 再放回 B ),再把 A 中对应的商品剔除。如果 A_array[i] = False ,就继续遍历。如果 B 中全都是 False ,就结束。PS:如果你抽到了 j-i ,就要把 j 删除,加入 i ,对每个发票打个标记,表示如果删除当前发票,需要加入哪些发票。
    3 )直到 A 或者 B 为空,或 B 中找不到满足条件的发票为止。

    时间复杂度就不算了,随机数据的耗时肯定是大大小于最差复杂度的。如果数据量不大,应该是可行的。
    tmsdy0404
        4
    tmsdy0404  
    OP
       2022-03-19 19:55:27 +08:00
    @wa007 量有点大啊,没办法把集合 A 的所有组合全部弄出来。
    这是实际的数据,虽然商品各类不多,但有的商品数量是 40000 个,
    单这个商品就有 2 的 40000 次方-1 种组合,这个量级没法弄吧


    ![quicker_9f6f1ecd-2481-4cfe-8ab7-855eabf3ee7f.png]( https://s2.loli.net/2022/03/19/BvxKHk78uziVUm9.png)
    wa007
        5
    wa007  
       2022-03-19 20:10:40 +08:00
    你看下背包算法,实现第一步不需要「 2 的 40000 次方-1 种组合」,复杂度主要跟 `PN` 有关
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5445 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 03:34 PVG 11:34 LAX 19:34 JFK 22:34
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86