P3847马云(贪心)

来源:互联网 发布:windows找不到某个exe 编辑:程序博客网 时间:2024/06/05 16:53

问题描述

Mr_he 因讨厌马云而彻底放弃网购,他的日常用品都要到商场去购买,而且必须付现金。但是现
金购买,经常会遇到找零的问题,那么现在请你帮助他解决这样一个问题: 现在 Mr_he 手上有 n
种不同面值的硬币,每种硬币有无限多个。为了方便购物,他希望带尽量 少的硬币,但是要能组合出 1 到 m 之间的任意值。

输入格式

第一行为两个整数:m 和 n,他们的意义如题目描述。 接下来的 n 行,每行一个整数,第 i+1 行的整数表示第 i 种硬币的面值

输出格式

最少需要携带的硬币数量,如果无解则输出-1

样例输入

20 4
1
2
5
10

样例输出

5

题解

sum表示目前小于等于sum的种类可以被表示,那么下一次能够增加的面额一定小于等于sum+1,因为如果大于了sum+1那么从sum+1到此之间的值一定不能被满足。
此贪心正确性是显然的。
考场上贪心向应该从小到大贪心,因为如果从大到小贪心不能满足小于此面额时的种类数可行,并且通过之前的值可能表示此时的值。

代码

#include<stdio.h>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<queue>#include<vector>#include<iostream>using namespace std;#define int long long#define maxn 101int n,m;int a[maxn];int cnt[maxn];int ans;int i,j;int sum;main(){    cin>>m>>n;    for(i=1;i<=n;i++) cin>>a[i];    sort(a+1,a+1+n);    if(a[1]==-1){cout<<-1;return 0;    }    while(sum<m){        for(i=n;i>=1;i--){            if(a[i]<=sum+1){                sum+=a[i];                ans++;                break;            }        }    }    cout<<ans;}
原创粉丝点击