当前位置: 首页 > news >正文

北大oj Coins

Problem: 北大oj Coins

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code

思路

题目要求我们找出所有可能组成的金额总数,给定一系列硬币面值和每种硬币的数量。我们使用动态规划来解决这个问题。关键在于如何处理每种硬币数量大于1的情况,这需要对余数进行分组,以便于在遍历时能够有效地更新状态。

解题方法

我们首先初始化一个布尔数组dp,其长度为最大目标金额m加上1。数组中的每个元素表示是否可以组成对应位置的金额。接下来,对于每种硬币,根据其数量的不同,采取不同的策略更新dp数组。如果硬币数量为1,则直接更新dp数组;如果硬币数量多且硬币总价值大于m,则可以视为无限数量的硬币;否则,需要根据余数进行分组更新。

复杂度

时间复杂度:

O ( n × m ) O(n×m) O(n×m),其中n是硬币种类数,m是目标金额。

空间复杂度:

O ( m ) O(m) O(m),主要取决于dp数组的大小。

Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;public class Main {static int MAXN = 110;static int MAXM = (int) (1e5 + 10);static int[] val = new int[MAXN];static int[] cnt = new int[MAXN];static boolean[] dp = new boolean[MAXM];static int n, m;public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {n = (int) in.nval;in.nextToken();m = (int) in.nval;if (n != 0 || m != 0) {for (int i = 1; i <= n; i++) {in.nextToken();val[i] = (int) in.nval;}for (int i = 1; i <= n; i++) {in.nextToken();cnt[i] = (int) in.nval;}out.println(deal());}}out.flush();out.close();br.close();}private static int deal() {// TODO Auto-generated method stubArrays.fill(dp, 1, m + 1, false);dp[0] = true;for(int i = 1; i <= n; i++) {if(cnt[i] == 1) {for(int j = m ; j >= val[i]; j--) {if(dp[j - val[i]]) {dp[j] = true;}}} else if(val[i] * cnt[i] > m) {for(int j = val[i]; j <= m; j++) {if(dp[j - val[i]]) {dp[j] = true;}}} else {// 根据余数分组for (int mod = 0; mod < val[i]; mod++) {int trueCnt = 0;for (int j = m - mod, size = 0; j >= 0 && size <= cnt[i]; j -= val[i], size++) {trueCnt += dp[j] ? 1 : 0;}for (int j = m - mod, l = j - val[i] * (cnt[i] + 1); j >= 1; j -= val[i], l -= val[i]) {if (dp[j]) {trueCnt--;} else {if (trueCnt != 0) {dp[j] = true;}}if (l >= 0) {trueCnt += dp[l] ? 1 : 0;}}}}}int ans = 0;for(int i = 1; i <= m; i++) {if(dp[i]) {ans++;}}return ans;}}

相关文章:

  • 哈希表、哈希函数以及算法的时间复杂度和空间复杂度
  • tiaoshixitong
  • RTthread+STM32F407ZGTx+烟雾报警检测+蜂鸣器报警+LED闪烁||使用RTthread Studio
  • Linux安全:保护你的数字堡垒
  • 多功能投票系统(ThinkPHP+FastAdmin+Uniapp)
  • 什么牌子充电宝值得买?这几款充电宝好用到没话说!内行人推荐
  • c语言单元测试构建
  • Windows defender bypass | 免杀
  • Java解析Json格式数据
  • Multisim软件仿真之频谱分析仪
  • 【MySQL】复合查询和内外连接
  • Qt系统相关
  • 利用K8S技术栈打造个人私有云
  • 随心而遇,跟着感觉走
  • 高考专业抉择探索计算机专业的未来展望及适合人群
  • ES6指北【2】—— 箭头函数
  • [ 一起学React系列 -- 8 ] React中的文件上传
  • CentOS从零开始部署Nodejs项目
  • conda常用的命令
  • CSS 专业技巧
  • HTTP--网络协议分层,http历史(二)
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • isset在php5.6-和php7.0+的一些差异
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • JavaScript-Array类型
  • JavaScript对象详解
  • java正则表式的使用
  • jQuery(一)
  • nginx 配置多 域名 + 多 https
  • node 版本过低
  • October CMS - 快速入门 9 Images And Galleries
  • python 装饰器(一)
  • Redis字符串类型内部编码剖析
  • vue-cli在webpack的配置文件探究
  • WePY 在小程序性能调优上做出的探究
  • Zsh 开发指南(第十四篇 文件读写)
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端js -- this指向总结。
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 一个项目push到多个远程Git仓库
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • ​数据结构之初始二叉树(3)
  • # Panda3d 碰撞检测系统介绍
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (27)4.8 习题课
  • (30)数组元素和与数字和的绝对差
  • (4.10~4.16)
  • (HAL库版)freeRTOS移植STMF103
  • (libusb) usb口自动刷新
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (九)One-Wire总线-DS18B20
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (十五)使用Nexus创建Maven私服