Baltic 2010 Candies

本文介绍了一种优化动态规划算法的方法,通过使用特定的递归函数和区间处理技巧,将复杂度从O(N^3)降低到O(n^2.5)。文章详细描述了一个实例,展示了如何利用该算法解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.cppblog.com/jsn1993/archive/2010/05/21/116026.html 上有一个很不错的方法,但可惜最坏情况下区间数还是O(n)级别的(b[1], b[2], ..., b[i]分别为2^i,后面的都取7000, 则所有偶数都可以组合出来,奇数都不可组合出来),因此其动规还是O(N^3)级别的。如果分组优化,把每组的大小设为(sqrt(n*4+1)+1)/2,可以把最坏情况的复杂度降至O(n^2.5)。

 

后来看了官方题解,发现其方法非常巧妙,核心为以下函数:

Algorithm 1 generate((p1 , p2 , p3 , ..., pm ), S)
 if m = 1 then
    S is one of the desired structures
 else
    S1 = add(S, (p1 , p2 , ..., p m/2 ))
    S2 = add(S, (p m/2 +1 , ..., pm ))
    generate((p m/2+1 , ..., pm ), S1 )
    generate((p1 , p2 , ..., p m/2 ), S2 )
 end if

 

参数中S为已经获得的可组合出的数,p1..pm为要加入的包。该算法可在O(B * n * m log m)内运行完毕,并能获得S加上p的所有m-1个元素的子集所能得到的组合结果。

由于官方数据比较厚道,区间数很少,我想到在以上算法的基础上加上区间处理的优化,于是程序运行的效果非常好……

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值