1961: 硬币组合

 

 这道题目是一道经典的DP:

讲一下思路:

f[i]:指i元可以用最少多少张钞票凑齐,凑不齐的话值为-1

先将f数组初始化为无穷大(因为后面有min操作所以不能用-1)

输入的同时将f[a[i]]设为1(举个例子:有一张五元的钞票要凑5元,可以只用一张钞票完成任务)

将f[0]设为0(又一个初始化)

再来一个n2的双重i j 循环,i从1到s 表示要凑齐i元,j从1到n表示遍历一遍所有的钞票。

先判断i-a[j]是否超界。(后面会用到)

我们可以从要凑成的钱数里减去5元再在所用的钞票数里加上1,用算式表达:f[i-a[j]]+1,还要再f[i]和它之间去小值(因为f[i]可能之前已经有值了)

最后判断f[s]是否为最大值(0x3f3f3f3f)如果是的话,说明凑不出来,输出-1,否则输出它的值。

程序结束。

程序:

#include<bits/stdc++.h>
using namespace std;
int s,n,f[100100]={0},a[60]={0};
int main()
{
#ifdef LOCAL
    freopen( "1.in", "r", stdin );
    freopen( "1.out", "w", stdout );
#endif
    scanf("%d%d",&s,&n);
    memset(f,0x3f3f3f3f,sizeof f);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        f[a[i]]=1;
    }
    f[0]=0;
    for(int i=1;i<=s;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i-a[j]>=0)
            {
                f[i]=min(f[i],f[i-a[j]]+1);
            }
        }
    }
    if(f[s]==0x3f3f3f3f) cout<<"-1";
    else cout<<f[s];
    return 0;
}

 

posted @ 2022-10-13 22:43  王浩泽  阅读(30)  评论(0编辑  收藏  举报