求解,硬币组合最小总和算法

流星亚瑟 2018-02-22 03:10:32
最近想到个问题,应该有人发表过类似文章,如果有相关烦请给个链接,谢谢

题目:

设有硬币10元,5元,2元,1元,个数为 c1, c2, c3, c4 (c1, c2, c3, c4 >=0)
现需支付金额K元, K <= 10 * c1 + 5 * c2 + 2 * c3 + 1 * c4
求每种硬币的数量x1, x2, x3, x4,
使得总金额10 * x1 + 5 * x2 + 2 * x3 + 1 * x4 >= K 且总额最小。


我这里的问题在于不同于网上的最少硬币数量,而是最少总和
比如个数为 1, 1, 3, 0 ,K = 8时,
最少硬币数量算法计算结果是 1,0,0,0 总额为10元
而这里的正确答案应该是 0,1,2,0 总额为9元

我尝试百度了一下,只是找到了最少硬币数量的算法,不知最少总额如何计算,求教了。
...全文
1137 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanta 2018-09-08
  • 打赏
  • 举报
回复
这个题的数值中有特殊性,所以有非常简单的算法。
金额有10、5、2、1四种,每种都是下一个的两倍或两倍多。
这就简单了。从最多的向下找就行了,比如说79,先看10元的,7张;剩9元,5元的,1张;剩4元,2元的2张,(最后要判断下是否还有余,有的话,最后一项+1)结束。
如果指定一元的数量(X4已知),题目要变形下。变形为:
10 * x1 + 5 * x2 + 2 * x3 >= K - 1 * x4
代码:
int money=你要求的数字;
int x1=money/10;
money=money%10;
int x2=money/5;
money=money%5;
int x3=money/2;
money=money%2;
if(money!=0)X3++;
636f6c696e 2018-07-31
  • 打赏
  • 举报
回复
我想到个实现简单的算法
遍历所有选取方式,将总和添加到数据结构。
排序后依次遍历就能找到最接近总额的组合
只是算法复杂度高一点
Xiao菜瓜 2018-07-30
  • 打赏
  • 举报
回复
import java.util.*;
public class Main {
public static void main(String[] args){
int ans[]=new int[10000]; //储存可以表达那些结果

int arr[]={10,5,2,1};
int num[]=new int[4]; //保存每个硬币的个数
Scanner sc=new Scanner(System.in);

int moneySum=0;
for(int i=0;i<4;i++){ //输入每个硬币的个数
num[i]=sc.nextInt();
moneySum+=num[i]*arr[i];
}

for(int i=0;i<=moneySum;i++) //初始化都为-1
ans[i]=-1;


//dp看可以结合的所有钱的情况
for(int i=0;i<4;i++){
ans[0]=0;
if(num[i]!=0){
for(int j=0;j<=moneySum;j++){
if(ans[j]!=-1)
ans[j]=num[i];
else if(j-arr[i]>=0&&ans[j-arr[i]]!=-1)
ans[j]=ans[j-arr[i]]-1;
}
}
}

int n=sc.nextInt(); //输入要给的钱数
for(int i=n;i<=moneySum;i++)
if(ans[i]!=-1){
System.out.println(i);
break;
}
}
}

结果:
根据这个最小值然后用贪心算法就能解决这个怎么组成的~~
Xiao菜瓜 2018-07-30
  • 打赏
  • 举报
回复
感觉像是动态规划吧~~
流星亚瑟 2018-02-22
  • 打赏
  • 举报
回复
额,因为例子中的c4给定为0了
引用 1 楼 hdt 的回复:
你的答案似乎不对啊? 为何不是c4 等于 8呢?
真相重于对错 2018-02-22
  • 打赏
  • 举报
回复
你的答案似乎不对啊? 为何不是c4 等于 8呢?

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧