24数媒Java上机测试1

news/发布时间2024/5/10 23:04:10

题目:

美国邮票的面值共有1, 10, 21, 34, 70, 100, 350, 1225, 1500九种(单位为美分)。现给定一个邮资的价格n(以美分为单位),如果规定所贴邮票面值总和必须等于n,请输出最少要贴几张邮票。为了简化程序,我们假设只有1, 10, 21, 34四种面值。

输入格式:

为一个整数n。(0<n<1000)。测试用例保证合法且均可以用int存储。

输出格式:

也是一个整数,为所贴邮票的张数。

输入样例:

22

输出样例:

2

分析:

1、动态规划:

初始化——
1 int[] dp = new int[n+1];
2 for (int i = 1; i <= n; i++) {
3     dp[i] = i;
4 }
int[] dp: 存储计算结果,防止重复计算.
dp[i]:组成总面值为 i 的邮票数,因为邮票数>=1,为了不影响状态转移方程的计算,初始化的dp[i]应该取得它可以取到的最大值或更大,所以取dp[i] = i 或更大,即邮票面值为i时邮票数最多是i. 且题目0 < n < 1000,取不到0,也就无所谓i 从1开始还是从0开始.
状态转移方程——
1 for (int i = 1; i <= n; i++) {
2     for (int stamp : stampsPrice) {
3         if (i >= stamp) {
4             dp[i] = Math.min(dp[i], dp[i - stamp] + 1);//状态转移方程
5          }
6      }
7 }    
第一个循环计算出每个dp[i]的值,
dp[i] = Math.min(dp[i], dp[i - stamp] + 1);动态规划的核心,更新dp[i],需要判断面值是否大于或等于stamp,因为面值小于stamp会导致dp[i - stamp]超出数组范围,1是那一张stamp的数量

2、回溯算法

public class stamp {public static void main(String[] args) {int[] stamps = {1, 10, 21, 34}; // 邮票面值int target = 5; // 目标邮资System.out.println("最少需要邮票数量: " + minStamps(stamps, target));}public static int minStamps(int[] stamps, int target) {int[] minCount = {1000}; // 初始化最小邮票数量backtrack(stamps, target, 0, 0, minCount); // 调用回溯函数return minCount[0];}public static void backtrack(int[] stamps, int remain, int count, int start, int[] minCount) {if (remain == 0) { // 如果剩余面值为0,表示找到一种组合minCount[0] = Math.min(minCount[0], count); // 更新最小邮票数量return;}if (remain < 0 || start == stamps.length) { // 如果剩余面值小于0或者已经遍历完所有面值,直接返回return;}for (int i = start; i < stamps.length; i++) { // 从当前面值开始尝试if (count + 1 < minCount[0]) { // 剪枝:如果当前邮票数量已经大于最小数量,直接返回backtrack(stamps, remain - stamps[i], count + 1, i, minCount);} else {return;}}}
}

3、分支定界法

public class stamp {public static void main(String[] args) {int[] stamps = {1, 10, 21, 34}; // 邮票面值int target = 22; // 目标邮资System.out.println("最少需要邮票数量: " + minStamps(stamps, target));}public static int minStamps(int[] stamps, int target) {Arrays.sort(stamps); // 将邮票面值排序,方便进行剪枝int[] minCount = {1000}; // 初始化最小邮票数量backtrack(stamps, target, 0, 0, minCount); // 调用回溯函数return minCount[0];}public static void backtrack(int[] stamps, int remain, int count, int start, int[] minCount) {if (remain == 0) { // 如果剩余面值为0,表示找到一种组合minCount[0] = Math.min(minCount[0], count); // 更新最小邮票数量return;}if (start == stamps.length || remain < 0) { // 如果已经遍历完所有面值或者剩余面值小于0,直接返回return;}// 计算当前面值能够使用的最大数量,即剩余面值除以当前面值int maxCount = remain / stamps[start];// 剪枝:如果当前邮票数量加上剩余面值除以当前面值的最大数量仍然大于等于当前最小数量,直接返回if (count + maxCount >= minCount[0]) {return;}// 逐个尝试当前面值可使用的数量,并递归搜索for (int i = maxCount; i >= 0; i--) {backtrack(stamps, remain - i * stamps[start], count + i, start + 1, minCount);}}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/13768175.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

CMake链接库,会检索库引用头文件路径

当使用CMake,target_link_libraries来链接静态库文件那边的头文件路径时,如果是跨了两层以上(即calculter到common这样),会导致CMake报错。add.h没有找到common.h头文件路径。一般来说,编译时候会对头文件(.h)包含在源文件(.cpp)的头部,这时就会检查链接库的头文件路…

使用ollama分别在我的window、mac、小米手机上部署体验llama3-8b

1、ollama到底是个什么玩意 一句话来说, Ollama 是一个基于 Go 语言开发的简单易用的本地大模型运行框架。可以将其类比为 docker(有类似docker中的一些常规命令list,pull,push,run 等等),事实上确实也制定了类似 docker 的一种模型应用标准,在后边的内容中,你能更加真切…

pwn知识——劫持__malloc_hook(在加入tcache以后)

导论 动调是最好的导师! malloc_hook函数解析 malloc_hook是malloc的钩子函数,在执行malloc时,会先检测__malloc_hook的值,如果malloc_hook的值存在,则执行该地址(值里边表现为十六进制,可以成为地址),也就是说,如果我们成功劫持malloc_hook以后并修改它的值为one_ga…

4.21 团队作业——第二天

今天进行了晨会主要内容是进行了任务的时间管理分配,每个团队成员领取了任务,并且进行了任务的时间限制,燃尽图的书写概况

IEAD添加插件生成UML图

使用IDEA中生成UML(统一建模语言) 一、准备环境 在Ubuntu环境下进行配置使用,工具和插件在Windows环境下也有版本,需要的工具、插件都是相同的,同样安装配置即可。 。IDEA社区版:因为免费 。插件PlantUML Parser:生成".puml"文件 。GrapHviz:通过puml文件生成…