题目大意:从N个正数的序列中,选出一些数,使它们的和等于给定值M,要求选出的一组数是所有可能的组合中最小的。所谓组合 A < 组合B,是指当A和B都是升序排列时,满足A[0] = B[0], A[1] = B[1]......A[k-1]=B[k-1], A[k] < B[k]......。
时间限制200ms,只要求输出最小的组合,直接的想法就是先按升序排序,然后从第一个元素开始dfs,直到搜索到和为M的组合,肯定是最小的组合。但这样做会有三个测试点超时,因此必须考虑剪枝。
① 如果之前已经找到解,那么直接return。设置一个引用变量 flag实现这个功能。
② 如果当前的和大于M,那么直接return。(这个我没有想到)
③ 此外,递归的边界 index == v.size(),需要写在判断当前和是否等于M之后,否则如果组合含有最后一个元素的话,会不经过判断直接return,从而丢解。
还有一个坑点是,最后一个测试点是所有数的和小于M的情形,这种情况不可能有解,但是用dfs会超时。因此在输入时就需要记录所有元素的和。
AC代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<map>
#include<algorithm>
#include<cmath>
#pragma warning(disable : 4996)
using namespace std;
vector<int> coins;
void dfs(int i