收银员现有 n 张面值分别为 v
的纸币。若找零金额为 m,则一共有多少种找零方法?
注:0
输出格式
若有解,则输出全部找零方案,每输出一种 若无解,则输出“None”
输入样例1
6 3 1 4 3 2 7 9
结尾无空行
输出样例1
3 1 3 2 3 4 2 4 3 2 2 7
输入样例2
5 5 3 4 6 7 2
结尾无空行
输出样例2
None
知识点:回溯,剪枝。
思路:本题为子集问题,(即可以分为选与不选两种情况,不需要用个for循环,直接在dfs中写出两种情况,在此基础上进行剪枝)dfs(i,sum,op)(i为第i个元素,sum为选中的元素和,op是数组用来标记第i个元素选不选)
纠正:刚开始在dfs中用for循环进行遍历访问,其实不用,因为该题为子集问题不需要,for一般用于全排列
代码:
#includeusing namespace std; int n; int rm = 0; int op[1005]; int v[1005]; int m; int flag = 0; void dfs(int i,int sum,int cnt) { if (i>n) { if (sum == m) { flag = 1; int j = cnt; for (int k = 1;k <= n;k++) { if (j == 1 && op[k] == 1) { cout << v[k] << endl; } else if (op[k] == 1) { cout << v[k] << " "; j--; } } } return; } op[i] = 1; if(sum + v[i]<=m) dfs(i + 1, sum+v[i],cnt+1); op[i] = 0; dfs(i + 1, sum,cnt); } int main() { cin >> n; for (int i = 1;i <= n;i++) { cin >> v[i]; rm += v[i]; } cin >> m; dfs(1,0,0); if (flag == 0) cout << "None" << endl; }



