1 条题解
-
0
思路:先进行搜索一次结果,并且保证本次搜索结果的面值尽可能的出现5,因为硬币数量是一定的,只有至少出现5和三个1,才能进行拆分出更多可能(只有1和2是没法拆分的),一个5可以拆成3个1和1个2,给3个1分配给搜索出的三个1,就能保证硬币数量不变的情况下又凑出另一种可能了。还有细节部分看代码 图解拆分:
``` import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { // 面值数组,5元、2元、1元 static int[] money = new int[]{5, 2, 1}; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int T = sc.nextInt(); // 测试案例数量 for (int i = 0; i < T; i++) { int n = sc.nextInt(); // 盒子数量 int m = sc.nextInt(); // 钱的总额 if (m == 0 || n == 0) { System.out.println(0); } else { List<Integer> res = new ArrayList<>(); dfs(n, m, 0, res); // 调用深度优先搜索 int CNT5 = 0; int CNT1 = 0; long ans = res.isEmpty() ? 0 : 1; for (int num : res) { if (num == 5) { CNT5++; } else if (num == 1) { CNT1++; } } // 计算额外的数量 int cnt = Math.min(CNT5, CNT1 / 3); if (CNT5 >= 1 && CNT1 >= 3) { ans += cnt; } System.out.println(ans); } } } // 深度优先搜索 public static boolean dfs(int n, int m, int cur, List<Integer> res) { if (m == 0 && n == 0) { return true; // 找到符合条件的组合 } if (m < 0 || n == 0 || m == 0) { return false; // 不符合条件的情况 } for (int i = cur; i <= 2; i++) { res.add(money[i]); // 将当前面值添加到结果列表中 boolean a1 = dfs(n - 1, m - money[i], i, res); // 递归调用 if (a1) return true; // 如果找到符合条件的组合,直接返回true else res.remove(res.size() - 1); // 否则,回溯,移除最后添加的面值 } return false; // 未找到符合条件的组合 } } ```
信息
- ID
- 2
- 时间
- 1000ms
- 内存
- 32MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 32
- 已通过
- 5
- 上传者