0-1背包扩展:要求所选择的物品必须恰好装满背包。
一般思路:设计dp[i][j]为前i件物品恰好体积总和为j时的最大价值,其状态转移01背包完全一致,但初始状态变为:dp[0][0]为0,而其它dp[0][j](前0件物品体积总量为j)值均为负无穷或不存在,最终得ans=dp[n][s]
此类问题不扫描到最后一件物品没有办法得到最终结果,也无法判断之前的结果是否最接近,所以只能把状态保留下来。
题目大意:一串数字,每个前面加+or-,和能否整除k
数学基础:
1、a|=b 即a=a|b 其中|为位或运算(则a、b中有一个为true则a为true)
a&=b 即a=a&b 其中&为位与运算
2、模法分配律,即(a+b+c)%k=(a%k+b%k+c%k)%k
技巧:1、右移100为负数腾空间(k<=100)
2、bool dp[i][j]表示到第i个数模k是否有可能等于j,最终结果为dp[N+1][0+100]
思路和代码参考:链接
AC代码:
#include <iostream>