【PTA】凑零钱

分手后的思念是犯贱 2023-07-03 02:38 93阅读 0赞

题目重述

韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 104枚来自各个星球的硬币,需要请你帮她盘算一下,是否可能精确凑出要付的款额。

输入格式:

输入第一行给出两个正整数:N(≤104)是硬币的总个数,M(≤102 )是韩梅梅要付的款额。第二行给出 N 枚硬币的正整数面值。数字间以空格分隔。

输出格式:

在一行中输出硬币的面值 V1 ≤V2 ≤⋯≤Vk ,满足条件 V1 +V2 +…+Vk =M。数字间以 1 个空格分隔,行首尾不得有多余空格。若解不唯一,则输出最小序列。若无解,则输出 No Solution。

注:我们说序列{ A[1],A[2],⋯ }比{ B[1],B[2],⋯ }“小”,是指存在 k≥1 使得 A[i]=B[i] 对所有 i<k 成立,并且 A[k]<B[k]。

输入样例 1:

  1. 8 9
  2. 5 9 8 7 2 3 4 1

输出样例 1:

  1. 1 3 5

输入样例 2:

  1. 4 8
  2. 7 2 4 3

输出样例 2:

  1. No Solution

题解

这道题可以说是一个0-1背包问题或者回溯法典型例题,使用回溯法的算法框架(其实回溯法的核心就是深度优先搜索),找到符合条件的输出就可以。

需要注意的是,这道题让求最小序列,我们需要提前将数组排序,然后再进行回溯法求解,求出来的第一组符合条件的序列就是我们要求的最小序列。

如果你得测试点超时,你可以通过两种方式排查:

  • 是否判断 所有的钱币面额加起来都小于m
  • 你的递归终止条件是否合理,是否做了无用功。

C++ AC

  1. #include <iostream>
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. int n,m;
  5. int current=0;
  6. int arr[10010];
  7. bool isFind=false;//是否已经找到
  8. bool flag[10010];
  9. void find_(int i)
  10. {
  11. if(i==n)
  12. {
  13. return;
  14. }
  15. if (current> m)
  16. {
  17. return ;
  18. }
  19. current+=arr[i];
  20. flag[i]=true;
  21. if(isFind)
  22. {
  23. return;
  24. }
  25. if(current==m)//找到了
  26. {
  27. for(int j=0; j<n; j++)
  28. {
  29. if(flag[j])//如果我们要这个
  30. {
  31. if(!isFind)//如果是第一次输出
  32. {
  33. cout<<arr[j];
  34. isFind=true;
  35. }
  36. else
  37. {
  38. cout<<" "<<arr[j];
  39. }
  40. }
  41. }
  42. }
  43. else
  44. {
  45. find_(i+1);
  46. }
  47. //回溯到之前的状态
  48. current-=arr[i];
  49. flag[i]=false;
  50. //递归下一个
  51. find_(i+1);
  52. return;
  53. }
  54. int main()
  55. {
  56. int sum=0;
  57. memset(flag,0,sizeof(flag));
  58. cin>>n>>m;
  59. for(int i=0; i<n; i++)
  60. {
  61. cin>>arr[i];
  62. sum+=arr[i];
  63. }
  64. if(sum<m)
  65. {
  66. cout<<"No Solution";
  67. }
  68. else
  69. {
  70. sort(arr,arr+n);
  71. find_(0);
  72. if(!isFind)
  73. {
  74. cout<<"No Solution";
  75. }
  76. }
  77. return 0;
  78. }

发表评论

表情:
评论列表 (有 0 条评论,93人围观)

还没有评论,来说两句吧...

相关阅读

    相关

    前言 > 配凑法也是高中数学中比较常用的一种数学方法。 使用场景 为了将分式函数化简,使用配凑法; 为了使用均值不等式,使用配凑法; 典例剖析

    相关 PTA零钱

    题目重述 韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩梅梅手边有 104枚来

    相关 零钱问题

    题目:给你k种面值的硬币,面值分别为 c1, c2 … ck,每种硬币的数量无限,再给一个总金额 amount,问你amount 最少需要几枚硬币凑出这个金额,如果不可能凑出,

    相关 硬币问题

    / 给出k中面值的硬币,每种硬币的数量无限,再给一个总金额amount,问最少需要几枚硬币凑出这个金额,如果凑不出,返回-1 dp[i]定义:当目标金额为i时,至少

    相关 算式

    凑算式 (不知道为什么放不了图片.) 这个算式中A~I代表1~9的数字,不同的字母代表不同的数字。 比如: 6+8/3+952/714 就是一种解法, 5

    相关 算式

    看这个算式: ☆☆☆ \+ ☆☆☆ = ☆☆☆ 如果每个五角星代表 1 ~ 9 的不同的数字。 这个算式有多少种可能的正确填写方法? 173 +286 = 459 2

    相关 L3-001 零钱 深搜

    L3-001 凑零钱 (30 分) 韩梅梅喜欢满宇宙到处逛街。现在她逛到了一家火星店里,发现这家店有个特别的规矩:你可以用任何星球的硬币付钱,但是绝不找零,当然也不能欠债。韩