题目大意
有几个数字,问是否有其中几个数加起来等于给定的数,如果有多个结果,输出最小的一组。
https://pintia.cn/problem-sets/994805342720868352/problems/994805402305150976
解法一:dfs+特判
1 | #include<bits/stdc++.h> |
如果不加特判,那么最后一点会超时,29分,这显然不是很好的解法
解法二:0-1背包
首先需要把序列从大到小排列,然后在dp,为什么呢?
看一组样例:5 9 8 7 2 3 4 1,容量为9
我们可以这样想,我们可以一个一个数地放入“背包”,如果符合条件dp[j] <= dp[j-weight[i]]+value[i],那么我们就把i标记(flag[i][j] = 1),最终通过while遍历最小的数。当该放每组结果的最小的数时,由于我们是从大到小排列的,所以前面比它大的数已经把其他背包更新好了,比如1 3 5,由于3和5已经把背包8更新成8,所以1就被背包9标记了,所以其实我们最终是把每组结果在各个背包的第一个数(即小的数)标记,即大数把背包更新,最小的数在此铺垫上就被标记了,而题目要求我们输出最小的结果,所以这就是序列必须从大到小排列的原因。
启发:0-1背包由于我们是一个数一个数地放,所以当放第i个数时,前面i-1个数已经把背包更新好了,这就是铺垫,第i个数在此铺垫上更新背包。
1 | #include <iostream> |
