动态规划-找零钱问题

#include <iostream>
#define MAX 20
int c[MAX];//存储所有币值
int F[MAX];//存放1到n的各个值所需的币数

int min(int x,int y)  //取较小值函数
{
    return (x<y)?x:y;
}

int changeMaking(int D[],int m,int n) //m为D的len,n为金额
    {   int i;
        F[0]=0;
        printf("start m=%d n=%d\n",m,n);
        for(i=1;i<=n;i++) //从1 到n的各个值所需的币数
            {
            printf("+++++++++++++++++++++++++++++++++++++++start i=%d$ \n",i);
                int temp=10000,j=1;
                while(j<=m and i>=D[j])//选择,并且选择之后在总数的范围类
                {
                    int lasttemp=temp;
                    temp=min(F[i-D[j]],temp);//选择了之后,之前子问题最优值,本质是将问题分段,分为已解决和未解决的部分
                    //例如,总数为5,选择1,那么就要使用F[5-1]的值,如果使用5,那么就是使用F[5-5]的值
                    printf("start select D[%d]=%d$, <before F[%d=%d-%d]=%d$ min=%d> %d\n",j,D[j],i-D[j],i,D[j],F[i-D[j]],temp,lasttemp);
                    j=j+1;
                }

                F[i]=temp+1;
                printf("++++++++++++++++++++++++end F[%d]=%d$ \n",i,F[i]);


            }
        return F[n];
    }
//int main_ningqian()
int main()
{
    int n=3,m=15;

    c[1]=1;//可以凑齐
    c[2]=5;
    c[3]=11;

/*
    c[1]=2;//不能凑齐
    c[2]=4;
    c[3]=10;
*/

    /*
    printf("请输入有多少个纸币:");
    scanf("%d", &n);
    printf("请分别输入纸币的价值:");
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &c[i]);

    }
    printf("请输入金额:");
    scanf("%d", &m);
    */


    int number=changeMaking(c,n,m);
    printf("changeMaking=%d\n",number);

     int j=m,i,num=0;
     int arr[MAX];
     while(j>0)
     {
         for(i=n;i>0;i--)
         {
             if(j-c[i]>=0 and F[j-c[i]]==number-1) //要求j-c[i]>=0才有效,否则可能为负,而且F[]的值符合要求
             {
                 arr[num++]=c[i];
                 j=j-c[i];
                 number=number-1;
                 break;  //找到符合要求的币值,则break
             }
             else{ continue;}
         }
     }

     printf("find:");
     for (int i = 0; i<num; i++)

         printf("%d ", arr[i]);
     return 0;
}

/*log打印
start m=3 n=15
+++++++++++++++++++++++++++++++++++++++start i=1$
start select D[1]=1$, <before F[0=1-1]=0$ min=0> 10000
++++++++++++++++++++++++end F[1]=1$
+++++++++++++++++++++++++++++++++++++++start i=2$
start select D[1]=1$, <before F[1=2-1]=1$ min=1> 10000
++++++++++++++++++++++++end F[2]=2$
+++++++++++++++++++++++++++++++++++++++start i=3$
start select D[1]=1$, <before F[2=3-1]=2$ min=2> 10000
++++++++++++++++++++++++end F[3]=3$
+++++++++++++++++++++++++++++++++++++++start i=4$
start select D[1]=1$, <before F[3=4-1]=3$ min=3> 10000
++++++++++++++++++++++++end F[4]=4$
+++++++++++++++++++++++++++++++++++++++start i=5$
start select D[1]=1$, <before F[4=5-1]=4$ min=4> 10000
start select D[2]=5$, <before F[0=5-5]=0$ min=0> 4
++++++++++++++++++++++++end F[5]=1$
+++++++++++++++++++++++++++++++++++++++start i=6$
start select D[1]=1$, <before F[5=6-1]=1$ min=1> 10000
start select D[2]=5$, <before F[1=6-5]=1$ min=1> 1
++++++++++++++++++++++++end F[6]=2$
+++++++++++++++++++++++++++++++++++++++start i=7$
start select D[1]=1$, <before F[6=7-1]=2$ min=2> 10000
start select D[2]=5$, <before F[2=7-5]=2$ min=2> 2
++++++++++++++++++++++++end F[7]=3$
+++++++++++++++++++++++++++++++++++++++start i=8$
start select D[1]=1$, <before F[7=8-1]=3$ min=3> 10000
start select D[2]=5$, <before F[3=8-5]=3$ min=3> 3
++++++++++++++++++++++++end F[8]=4$
+++++++++++++++++++++++++++++++++++++++start i=9$
start select D[1]=1$, <before F[8=9-1]=4$ min=4> 10000
start select D[2]=5$, <before F[4=9-5]=4$ min=4> 4
++++++++++++++++++++++++end F[9]=5$
+++++++++++++++++++++++++++++++++++++++start i=10$
start select D[1]=1$, <before F[9=10-1]=5$ min=5> 10000
start select D[2]=5$, <before F[5=10-5]=1$ min=1> 5
++++++++++++++++++++++++end F[10]=2$
+++++++++++++++++++++++++++++++++++++++start i=11$
start select D[1]=1$, <before F[10=11-1]=2$ min=2> 10000
start select D[2]=5$, <before F[6=11-5]=2$ min=2> 2
start select D[3]=11$, <before F[0=11-11]=0$ min=0> 2
++++++++++++++++++++++++end F[11]=1$
+++++++++++++++++++++++++++++++++++++++start i=12$
start select D[1]=1$, <before F[11=12-1]=1$ min=1> 10000
start select D[2]=5$, <before F[7=12-5]=3$ min=1> 1
start select D[3]=11$, <before F[1=12-11]=1$ min=1> 1
++++++++++++++++++++++++end F[12]=2$
+++++++++++++++++++++++++++++++++++++++start i=13$
start select D[1]=1$, <before F[12=13-1]=2$ min=2> 10000
start select D[2]=5$, <before F[8=13-5]=4$ min=2> 2
start select D[3]=11$, <before F[2=13-11]=2$ min=2> 2
++++++++++++++++++++++++end F[13]=3$
+++++++++++++++++++++++++++++++++++++++start i=14$
start select D[1]=1$, <before F[13=14-1]=3$ min=3> 10000
start select D[2]=5$, <before F[9=14-5]=5$ min=3> 3
start select D[3]=11$, <before F[3=14-11]=3$ min=3> 3
++++++++++++++++++++++++end F[14]=4$
+++++++++++++++++++++++++++++++++++++++start i=15$
start select D[1]=1$, <before F[14=15-1]=4$ min=4> 10000
start select D[2]=5$, <before F[10=15-5]=2$ min=2> 4
start select D[3]=11$, <before F[4=15-11]=4$ min=2> 2
++++++++++++++++++++++++end F[15]=3$
changeMaking=3
find:5 5 5
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值