01背包变种(碎碎念...自用)

晚上看了一道题叫倍数问题
利用了01背包的方法来处理选取3个数满足3数之和对k取余为0的条件并且3个数之和最大,求出这个最大值。
看了这道题后突然发现自己只会最朴素(tu)的01背包
也就是还停留在从n件物品中选取物品装入容量为v的背包使总价值最大的01背包…只会敲这样的模板 而没有真正思考过可以利用01背包来解决的类似的其他问题。

之前是从前n件物品中选或不选物品
所以在第一层循环的时候已经遍历过了n件物品。

而这个题是从做过处理的n个数中选取3个,使满足余数条件
所以做法是每挑出一个数对它进行两层循环,遍历是第几个被选,被选中要满足怎样的余数条件。

嗯…还有就是假设我们之前选的数之和对k取余的余数为a,我们如果要另选一个数b,使他们加起来对k取余的余数结果要为c。
那么要选出来的这个b对k取余所需要满足的条件就是要等于
(c-a%k+k)%k

另外还是看到和数论有关的一点技巧
和这道题一点做法有点类似 也是一道蓝桥杯真题 叫k倍区间
思路是要求区间之和%k==0的区间 区间和呢又可以通过前缀和的方法来求,假设a,b是两个前缀和,也就是(a-b)%k == 0,也就是a%k ==b%k
于是把余数相同的前缀和存在一起,对它们进行两两配对求得答案。

而这道题是(a+b+c)%k == 0
变换一下就是 (a%k+b%k+c%k)%k == 0
这样呢 我们也可以把余数相同的数存放起来,经过排序后就能获得满足条件的数再进行下一步处理。
可以先从小到大排序再求余存放,这样取出的时候就能保证取到最大。

距离蓝桥杯比赛还有十几天,从去年7月份训练到现在,学到了很多东西,深知自己做得还远远不够,但我已足够认真的对待,所以无论结果如何不会有遗憾。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值