经典换硬币---简单题

第4章习题 (educoder.net)

 这个题我们一定知道如何进行分配是最优的方式,但是我们如何在众多方式中选出最优的方式就成了一个问题,我们首先想到的就是将他们都存起来,最后进行比较

上代码

#include<stdio.h>

int main()
{
    int count=0;//记录总共有几种方法
    int num;
    scanf("%d",&num);//输入钱
    int coin[1000][3]={0};//记录每一组的个数
    int sum[1000]={0};//记录每一组的总硬币数
    for(int i=num/5;i>0;i--)//i表示的5硬币的最多的枚数
    {
        for(int j=num/2;j>0;j--)//j表示2硬币最多的枚数
        {
            for(int t=num;t>0;t--)//t表示1硬币最多的枚数,每枚硬币都必须大于0
            {
                if((i*5+j*2+t)==num)
                {
                    coin[count][0]=i;
                    coin[count][1]=j;
                    coin[count][2]=t;
                    count++;//表示有多少种情况
                    
                }
            }
        }
    }
    for(int i=0;i<count;i++)
    {
        sum[i]=coin[i][0]+coin[i][1]+coin[i][2];
    }
    int min=sum[0];
    int m_min=0;//记录最少换法的小角标
    for(int i=1;i<count;i++)
    {
        if(min>sum[i])
        {
            m_min=i;
        }
    }
    if(count==1)
    {
        printf("只有一种换法%d,%d,%d",coin[m_min][0],coin[m_min][1],coin[m_min][2]);
    }
    else
    {
        printf("有至少两种换法\n");
        printf("硬币数量最少的为%d,%d,%d",coin[m_min][0],coin[m_min][1],coin[m_min][2]);
    }

    return 0;
}

 这里为什么需要1000个空间来存储呢?我一开始设置的是100个空间然后到了72的时候就已经无法实现了,那么我就改为了1000

那我们为什么要让i,j,k都要大于0呢,因为是题目规定

我们可以不申请那么多的空间吗,我想了想,我觉得可行

上代码

#include<stdio.h>

//不使用那么多空间的方式
int main()
{
    int num;
    scanf("%d",&num);//输入的钱
    int sum=0;//记录总硬币数
    int count=0;//记录共多少分发
    int coin[3]={0};//记录最少的那种换法,5,2,1
    for(int i=num/5;i>0;i--)
    {
        for(int j=num/2;j>0;j--)
        {
            for(int k=num;k>0;k--)
            {
                if((k+j*2+i*5)==num)
                {
                    if(count==0)
                    {
                        sum=i+j+k;
                        coin[0]=i;
                        coin[1]=j;
                        coin[2]=k;
                    }
                    count++;
                    if(sum>k+i+j)
                    {
                        sum=k+i+j;
                        coin[0]=i;
                        coin[1]=j;
                        coin[2]=k;
                    }
                    
                }
            }
        }
    }
    if(count==1)
    {
        printf("只有一种换法%d,%d,%d",coin[0],coin[1],coin[2]);
    }
    else
    {
        printf("有至少两种换法\n");
        printf("硬币数量最少的为%d,%d,%d",coin[0],coin[1],coin[2]);
    }


    return 0;
}

这是可以实现的

那么问题又来了,这中方式时间复杂度太高了吧n^3,会死人的,不能少点儿吗???

我们看看能不能实现吧

上代码

#include<stdio.h>

//可以不使用那么多的时间吗
int main()
{
    int num=0;
    scanf("%d",&num);
    int count=0;//记录总换法
    int sum=0;//记录总的硬币数
    int i,j,k;
    int coin[3]={0};//记录最少的那种换法,5,2,1
    for(i=num/5,j=num/2,k=num;i>0,j>0,k>0;i--,j--,k--)//不能这么搞
    //不能让他们同时改变,要一层一层的改变
    {
        if(num==(i*5+j*2+k))
        {
            if(count==0)
            {
                sum=i+j+k;
                coin[0]=i;
                coin[1]=j;
                coin[2]=k;
            }
            count++;
            if(sum>k+i+j)
            {
                sum=k+i+j;
                coin[0]=i;
                coin[1]=j;
                coin[2]=k;
            }
        }
    }
    if(count==1)
    {
        printf("只有一种换法%d,%d,%d",coin[0],coin[1],coin[2]);
    }
    else
    {
        printf("有至少两种换法\n");
        printf("硬币数量最少的为%d,%d,%d",coin[0],coin[1],coin[2]);
    }
    return 0;
}

这种方式是大错特错的,因为这道题的点应该是从内向外一次进行改变的,但是这里就成了一次进行了变化,根本就是不对的。

如果有什么好的办法可以解决时间复杂读的问题我还会回来的,如果有高手看到了这篇文章还望指点指点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值