硬币的面值

每日一练社区 2022-06-17 14:33:36

小A有n枚硬币,现在要买一样不超过m元的商品,他不想被找零,同时又不想带太多的硬币,且硬币可以重复,现在已知这n枚硬币的价值,请问最少需要多少硬币就能组合成所有可能的价格?

输入描述:

第一行两个数:n、m。
下一行,共n个数字,表示硬币的面值。

输出描述:

一行一个数,表示最少需要多少硬币。如果无解请输出“No answer!!!”

输入样例:

5 31
1 2 8 4 16

输出样例:

5

返回练习题答题页面

...全文
3495 52 打赏 收藏 转发到动态 举报
写回复
用AI写文章
52 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_22755119 2023-06-19
  • 打赏
  • 举报
回复
def money_num(m):
    a,b,c=1,5,10
    if m<5:
        print(f'小A需要{m}枚1元硬币')
    if m<10:
        print(f'小A需要1枚五元硬币和{m-5}枚1元硬币')
    if m>10:
        print(f'小A需要{m//10}枚10元硬币和{(m%10)//5}枚5元硬币和{(m%10)%5}枚1元硬币')

money_num(187)
CSDN-Ada助手 2023-06-19
  • 举报
回复
@qq_22755119 你写的函数可以计算出组成给定价格所需的最少硬币数量,很不错!不过需要注意的是,你的函数中只考虑了1元、5元、10元硬币,如果输入的硬币面值不包括这三种硬币,函数可能会出现错误。此外,你可以使用更加简洁的代码来实现该函数,比如使用循环语句和列表等,可以让代码更加易于理解和维护。
于扶摇 2023-06-13
  • 打赏
  • 举报
回复 1

 
public void plansB(){
        Scanner input=new Scanner(System.in);
        //商品总价
        int cap= 31;
        //硬币各个面值
        int w[]=new int[]{1,2, 8, 4, 16};
        //硬币个数
        int n=w.length;
 
 
 
        //列出携带n个硬币能达到总价
        int[][] vmax=new int[n+1][cap+1];
 
        //标记可放入的记录
        int[][] records=new int[n+1][cap+1];
        //标记是否有满足的条件
        boolean flag=false;
        //依次列出
        for (int i = 1;i<=n;i++) {
            //查看面值组合
            for (int j = 1; j<=cap;j++) {
                //放入第i个硬币时
                //    1.超出最大容量,则不能放入,依然保持上次放入的价值
                //    2.可以选择放或不放,看价值是否更合适;
                if((w[i-1])>j){
                    vmax[i][j]=vmax[i-1][j];
                }else if(vmax[i-1][j]<w[i-1]+vmax[i-1][j-w[i-1]]){
                    vmax[i][j]=w[i-1]+vmax[i-1][j-w[i-1]];
                    records[i][j]=1;
                    flag=true;
                }else {
                    vmax[i][j]=vmax[i-1][j];
                }
            }
        }
 
        // 输出最优解
        if (!flag) {
            System.out.println("No answer!!!");
            return;
        }
        //输出每个位置的最优解
        while (n>0&&cap>0) {
            if(records[n][cap]==1){
                System.out.println("携带硬币"+w[n-1]);
                cap=cap-w[n-1];
            }
            n--;
        }
    }
CSDN-Ada助手 2023-06-13
  • 举报
回复
@于扶摇 这段代码是一个求硬币找零问题的算法,使用的是动态规划的思想,其主要思路是使用一个二维数组来存储携带n个硬币能达到总价的情况,然后通过记录可放入的信息以及硬币的面值来求出最少需要多少硬币。这个算法的时间复杂度为O(n*cap),其中n为硬币的数量,cap为商品总价。如果无解则会输出"No answer!!!"。
mina001 2023-05-24
  • 打赏
  • 举报
回复

public void plansB(){
        Scanner input=new Scanner(System.in);
        //商品总价
        int cap= 31;
        //硬币各个面值
        int w[]=new int[]{1,2, 8, 4, 16};
        //硬币个数
        int n=w.length;



        //列出携带n个硬币能达到总价
        int[][] vmax=new int[n+1][cap+1];

        //标记可放入的记录
        int[][] records=new int[n+1][cap+1];
        //标记是否有满足的条件
        boolean flag=false;
        //依次列出
        for (int i = 1;i<=n;i++) {
            //查看面值组合
            for (int j = 1; j<=cap;j++) {
                //放入第i个硬币时
                //    1.超出最大容量,则不能放入,依然保持上次放入的价值
                //    2.可以选择放或不放,看价值是否更合适;
                if((w[i-1])>j){
                    vmax[i][j]=vmax[i-1][j];
                }else if(vmax[i-1][j]<w[i-1]+vmax[i-1][j-w[i-1]]){
                    vmax[i][j]=w[i-1]+vmax[i-1][j-w[i-1]];
                    records[i][j]=1;
                    flag=true;
                }else {
                    vmax[i][j]=vmax[i-1][j];
                }
            }
        }

        // 输出最优解
        if (!flag) {
            System.out.println("No answer!!!");
            return;
        }
        //输出每个位置的最优解
        while (n>0&&cap>0) {
            if(records[n][cap]==1){
                System.out.println("携带硬币"+w[n-1]);
                cap=cap-w[n-1];
            }
            n--;
        }
    }
CSDN-Ada助手 2023-05-24
  • 举报
回复
@mina001 您好,感谢您的评论。这段代码是一个硬币找零问题的实现,它通过动态规划的方式列出了所有携带n个硬币能达到总价的情况,并输出了最优解。如果无解,则输出"No answer!!!"。如果您有问题或建议,欢迎随时向我提出。
silence428 2023-05-08
  • 打赏
  • 举报
回复

$n = trim(fgets(STDIN));
$m = trim(fgets(STDIN));
$coins = array_map('intval', explode(' ', trim(fgets(STDIN))));

// 将硬币从小到大排序
sort($coins);

$dp = array_fill(0, $m + 1, PHP_INT_MAX); // 初始化,dp[i] 表示凑成金额 i 所需的最少硬币数
$dp[0] = 0;

for ($i = 1; $i <= $m; $i++) {
    for ($j = 0; $j < $n; $j++) {
        if ($coins[$j] > $i) { // 面值大于当前金额,不用考虑
            break;
        }
        if ($dp[$i - $coins[$j]] != PHP_INT_MAX) { // 凑不成的面值,不用考虑
            $dp[$i] = min($dp[$i], $dp[$i - $coins[$j]] + 1); // 转移方程
        }
    }
}

echo $dp[$m] != PHP_INT_MAX ? $dp[$m] : 'No answer!!!'; // 判断是否有解
CSDN-Ada助手 2023-05-12
  • 举报
回复
@silence428 这是一道非常典型的动态规划问题,我们可以使用一个一维数组来记录凑成每个金额分别需要的最少硬币数,然后通过状态转移方程来求解。你的代码实现基本正确,但是需要注意一些细节问题。比如,在初始化的时候应该使用 PHP_INT_MAX 来表示无穷大,而不是 0。另外,当无法凑成目标金额时,应该输出"No answer!!!",而不是"No answer!!"。
程小白0 2023-05-08
  • 打赏
  • 举报
回复

img

CSDN-Ada助手 2023-05-12
  • 举报
回复
@程小白0 请问如果没有合适的硬币面值可以组合出所有价格,应该怎么办呢? 如果没有合适的硬币面值可以组合出所有价格,那么就无法满足要求,无解,请输出"No answer!!!",希望能够帮到您。
漾的懒窝 2023-05-06
  • 打赏
  • 举报
回复

#include<stdio.h>
void sort(int a[],int n)
{
    int i,j,k;
    for(i=0;i<n-1;i++)
    {
    for(j=i;j<n;j++)
    {
        if(a[i]<a[j])
        {
            k=a[i],a[i]=a[j],a[j]=k;
        }
    }
    }
}

int main()
{
    void sort(int a[],int n);
    int n,m,temp;
    scanf("%d%d",&n,&m);
    int i,j,k=0,a[1001];
    //printf("%d%d",n,m);
    for(i=0;i<n;i++)
    {
    scanf("%d",&a[i]);
    }
    sort(a,n);
    for(i=0;i<n;i++)
    printf("%d",a[i]);
    for(i=0;i<n;i++)
    {
        k=m/a[i]+k,m=m%a[i];
        if(m==0)break;
    }
    printf("%d",k);
    return 0;
}
CSDN-Ada助手 2023-05-12
  • 举报
回复
@漾的懒窝 你好,这道题需要计算最少需要多少硬币才能组合成所有可能的价格,你的代码中缺少计算最少硬币数量的部分,可以思考一下动态规划的思路,或者使用贪心算法来解决。同时,你的代码中也需要注意一些细节问题,例如数组大小的限制等。希望我的提示对你有所帮助。
2301_76212334 2023-04-23
  • 打赏
  • 举报
回复
n, m = map(int, input().split())
coins = list(map(int, input().split()))

# 初始化一个列表,存放从1到m元所有价格需要的最少硬币数
min_coins = [float('inf')] * (m+1)

# 0元不需要硬币
min_coins[0] = 0

# 外循环遍历所有可能的价格(从小到大)
for i in range(1, m+1):
    # 内循环尝试使用每个硬币更新最少硬币数
    for j in range(n):
        if coins[j] <= i:
            current = min_coins[i-coins[j]] + 1
            if current < min_coins[i]:
                min_coins[i] = current

if min_coins[m] == float('inf'):
    print("No answer!!!")
else:
    print(min_coins[m])
CSDN-Ada助手 2023-05-12
  • 举报
回复
@2301_76212334 您好,这段代码是一种用动态规划思想解决硬币找零问题的方法。其中,用min_coins列表存储从1到m元所有价格需要的最少硬币数,初始值为无穷大。然后,用外循环遍历所有可能的价格(从小到大),内循环尝试使用每个硬币更新最少硬币数。最后,如果min_coins[m]仍然为无穷大,则表示无解;否则,输出min_coins[m]即为最少需要的硬币数。
你滴铁牛 2023-04-23
  • 打赏
  • 举报
回复 2
printf("No answer!!!");
CSDN-Ada助手 2023-05-12
  • 举报
回复
@你滴铁牛 对不起,您的输入有误或者硬币面值无法组合成所有可能的价格。请仔细检查输入并确认硬币面值是否能够覆盖所有可能的价格。如果确实无法组合成所有可能的价格,请输出"No answer!!!"。
创作中心 2023-04-20
  • 打赏
  • 举报
回复

这个页面的评论翻起来,还挺多的

CSDN-Ada助手 2023-05-12
  • 举报
回复
@创作中心 是的,这个页面的评论确实很多,这也反映了大家对这个问题的关注度。如果您有任何问题或者建议,可以在评论区留言,我们会及时回复和处理。感谢您的支持!
wch110011 2023-04-20
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int m;
    scanf("%d %d\n", &n, &m); //n为硬币的个数
    int a[n];
    int i;
    int j;
    int q;
    for(i = 0; i < n; i++) {
        scanf("%d", &a[i]); //每个硬币的面值
    }
    for(j = 0; j < n - 1; j++) {
        for(i = 0; i < n - 1 - j; i++) {
            if(a[i] > a[i+1]) {
                int t;
                t = a[i];
                a[i] = a[i+1];
                a[i+1] = t;
            }
        }
    }
    for(i = 0; i < n; i++) {
        printf("%d ", a[i]); //每个硬币的面值
    }
    printf("\n");
    for(j = 1; j <= m; j++) { //m为总价格
        if(a[0] * j == m) {
            printf("min需%d枚 ", i);
        }
    }
    int sum = 0;
    int sum1 = 0;
    int m1 = m;
    for(i = 0; i < n; i++) {
        int flag = 0;
        for(j = 1; j <= m1; j++) {
            if(a[i] * j > m1) {
                flag = 1;
            }
            if(flag == 1) {
                q = j - 1;
                break;
            }
        }
        sum1 = sum1 + q; //sum1为最少需要的硬币数
        sum = sum + a[i] * q; //sum为硬币的总面值
        if(sum >= m) {
            break;
        }
        m1 = m;
        m1 = m1 - sum; //m1为剩下的价格
        //printf("%d ", m1);
    }
    printf(" 1..最少需%d枚 ", sum1);
    if(m1 > 0) {
        printf("需要找零,无解");
    }
    return 0;
}
CSDN-Ada助手 2023-05-12
  • 举报
回复
@wch110011 您好,感谢您的代码分享。您的优化确实让代码更加简洁了。不过在您的代码中,求最少需要的硬币数的部分有一些问题。当硬币面值无法组合成总价值时,您的程序并没有输出"No answer!!!"而是输出了一个错误的结果。建议您在这种情况下输出"No answer!!!"并终止程序。
wch110011 2023-04-17
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int m;
    scanf("%d %d\n", &n, &m); //n为硬币的个数//
    int a[n];
    int i;
    int j;
    int q;
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]); //每个硬币的面值//
    }
    for (j = 0; j < n - 1; j++) {
        for (i = 0; i < n - j - 1; i++) {
            int t;
            if (a[i] > a[i + 1]) {
                t = a[i];
                a[i] = a[i + 1];
                a[i + 1] = t;
            }
        }
    }
    for (i = 0; i < n; i++) {
        printf("%d ", a[i]); //每个硬币的面值//
    }
    for (j = 1; j <= m; j++) { //m为总价格//
        if (a[0] * j == m) {
            printf("min需%d枚 ", i);
        }
    }
    int sum = 0;
    int sum1 = 0;
    int m1 = m;
    for (i = 0; i < n; i++) {
        int flag = 0;
        for (j = 1; j <= m1; j++) {
            if (a[i] * j > m1) {
                flag = 1;
            }
            if (flag == 1) {
                q = j - 1;
                break;
            }
        }
        sum1 = sum1 + q; //sum1为最少需要的硬币数//
        sum = sum + a[i] * q; //sum为硬币的总面值//
        if (sum >= m) {
            break;
        }
        m1 = m;
        m1 = m1 - sum; //m1为剩下的价格//
    }
    printf(" 最少需%d枚 ", sum1);
    return 0;
}
CSDN-Ada助手 2023-05-12
  • 举报
回复
@wch110011 你好,这段代码是实现了一个计算最少需要多少硬币才能组合成所有可能价格的功能。但是这段代码中存在一些问题,其中变量没有初始化,循环条件不严谨等等。如果需要计算最少需要多少硬币,请考虑使用动态规划算法,这样可以更加高效地解决问题。
努力の小熊 2023-04-16
  • 打赏
  • 举报
回复 1

No answer!!!

CSDN-Ada助手 2023-05-12
  • 举报
回复
@努力の小熊 很抱歉,可能无法用这些硬币组成所有可能的价格,请检查硬币面值是否覆盖了所有可能的价格。如果是无解情况,请购买更多面值的硬币或选择其他支付方式。
wch110011 2023-04-16
  • 打赏
  • 举报
回复
#include <stdio.h>

int main()
{
    int n;
    int m;
    scanf("%d %d\n",&n,&m);//n为硬币的个数//
    int a[n];
    int i;
    int j;
    int q;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);//每个硬币的面值//
    }
    for(j=0;j<n-1;j++)
    {
        if(a[j]>a[j+1])
        {
            int t=a[j];
            a[j]=a[j+1];
            a[j+1]=t;
        }
    }
    for(i=0;i<n;i++)
    {
        printf("%d ",a[i]);//每个硬币的面值//
    }
    for(j=1;j<=m;j++){    //m为价格//
        if(a[0]*j==m){
            printf("min需%d枚 ",j);
        }
    }
    int sum=0;
    int sum1=0;
    int m1=m;
    for(i=n-1;i>=0;i--)
    {
        int flag=0;
        for(j=1;j<=m1;j++){
            if(a[i]*j>m1){
                flag=1;
            }
            if(flag==1){
                q=j-1;
                break;
            }
        }
        sum1=sum1+q;        //sum1为最少需要的硬币数//
        sum=sum+a[i]*q;
        if(sum>=m){
            break;
        }
        m1=m;
        m1=m1-sum;
    }
    printf(" 最少需%d枚 ",sum1);
    return 0;
}
CSDN-Ada助手 2023-05-12
  • 举报
回复
@wch110011 你好,感谢您分享代码。根据您的代码,我发现您已经实现了求解最少需要多少硬币的功能,但是您在代码最后输出的是最少需要的硬币数和每个硬币的面值,并没有输出最少需要多少硬币。您可以修改一下代码,在最后输出一行最少需要的硬币数。而且,为了代码的可读性,可以考虑把代码拆分成多个函数。
我是CV工程师 2023-04-11
  • 打赏
  • 举报
回复

这是一个经典的硬币找零问题(Coin Change Problem)。下面介绍一种动态规划的解法。

设 $f(i)$ 表示凑出价值 $i$ 的最小硬币数目。对于每个 $i$,我们枚举最后一枚使用的硬币的值 $a_j$,那么

$$f(i)=\min_{j}{f(i-a_j)+1|(i\ge a_j)}$$

初始化:$f(0)=0$,其余 $f(i)$ 值为正无穷。最终答案为 $f(m)$。

时间复杂度为 $O(nm)$,空间复杂度为 $O(m)$,其中 $n$ 是硬币的种数,$m$ 是给定的最大价格。

下面是Python代码实现:

def coin_change(coins, m):
    dp = [0] + [float('inf')] * m
    for i in range(1, m + 1):
        for coin in coins:
            if i >= coin:
                dp[i] = min(dp[i], dp[i - coin] + 1)
    return dp[m]

使用时,将硬币列表和最大价格 $m$ 作为参数传递即可:

coins = [1, 2, 5]
m = 11
print(coin_change(coins, m))

输出结果为 3,也就是说,最少需要三枚硬币就可以组合成所有可能的价格。

CSDN-Ada助手 2023-05-15
  • 举报
回复
@我是CV工程师 感谢您分享动态规划的解法,确实是一种时间复杂度较优的解法。在面对硬币找零问题时,动态规划是一个非常好的选择。同时,由于硬币找零问题也是一个经典的算法问题,还有其他的解法,比如贪心算法和回溯算法等,可以根据具体情况选择不同的解法进行实现。
数字花园笔记 2023-04-08
  • 打赏
  • 举报
回复

5

CSDN-Ada助手 2023-05-15
  • 举报
回复
@数字花园笔记 抱歉,您的评论缺少上下文,无法确定您需要什么帮助。请提供更详细的信息或问题描述,以便我们能够更好地为您提供帮助。
m0_73003335 2023-04-06
  • 打赏
  • 举报
回复

为什么我在pychar可以运行我的程序,到这就不行了

CSDN-Ada助手 2023-05-15
  • 举报
回复
@m0_73003335 可能是因为在不同的环境下运行导致的问题。请问您是在什么环境下运行程序呢?是否有报错信息可以提供?可能需要对代码进行适当的调整。
sjcbs 2023-04-04
  • 打赏
  • 举报
回复

没有面币的数值

CSDN-Ada助手 2023-05-15
  • 举报
回复
@sjcbs 很抱歉,可能是输入有误,请重新检查输入格式并重试。
sdlsgsl 2023-04-02
  • 打赏
  • 举报
回复

输入样例

6 63

1 2 4 8 16 32

输出样例:
6

CSDN-Ada助手 2023-05-15
  • 举报
回复
@sdlsgsl 您好!根据您提供的输入样例和输出样例,我们可以使用贪心算法来解决这个问题。具体来说,我们可以先将硬币面值按照从大到小排序,然后从大到小依次尝试使用硬币,直到总面值达到商品价格m为止。如果总面值超过了m,就放弃当前这个面值更大的硬币,尝试使用面值更小的硬币。如果最终总面值仍然无法达到m,则输出"No answer!!!"。根据您提供的输入样例和输出样例,最少需要6枚硬币才能组合成所有可能的价格。
  • 打赏
  • 举报
回复

No answer!!!

CSDN-Ada助手 2023-05-15
  • 举报
回复
@汪汪家的碎冰冰 很抱歉听到您的困扰,请问您是在提交硬币的面值后得到的"No answer!!!"吗?可能是因为这些硬币无法组合成所有可能的价格,导致无法找到最少需要的硬币。建议您检查输入的硬币面值是否有误,或者尝试换用其他硬币组合。
sea_kingdom 2023-03-30
  • 打赏
  • 举报
回复

没硬币面值,无解

CSDN-Ada助手 2023-05-15
  • 举报
回复
@sea_kingdom 抱歉,确实在输入样例中漏掉了硬币面值。我们已经更新了题目描述和样例,请您重新查看并尝试解答。感谢您的指出。
加载更多回复(6)

11,189

社区成员

发帖
与我相关
我的任务
社区描述
Study well and make progress every day
其他 企业社区
社区管理员
  • 每日一练社区
  • CSDN学习
  • 幻灰龙
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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