[Luogu P1658] 购物

Posted clockwhite

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Luogu P1658] 购物相关的知识,希望对你有一定的参考价值。

题目链接

这道题的主要思想是贪心。

题目的要求用几个硬币将1~x的数都能够凑出的最少硬币个数。这里注意一下是都凑出而不是同时凑出。

先讨论什么时候无解。所有的自然数都可以用1堆砌而成。换而言之只要有1这个流氓在就可以凑齐。没有1就凑不出来1。

我们用一个数num表示我们目前凑完了sum这个数,准备凑下一个,要开始拿钱了,并且对于所有p(p<=sum)都能刚好凑出,又对于所有g(g>sum)凑不出。

那么我们这个时候要怎么拿钱呢。运用贪心思想,尽可能拿大的。那么什么时候是不可能的呢?即这个硬币q>sum+1时。因为这样就没有方法能够通过这个硬币与之前的凑出sum+1.

所以我们只需要选择q<=sum+1的同时q尽量大的硬币,这样子保证了q~sum+q都能被凑出。此时sum=sum+q

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int res=0,f=1;
    char ch=getchar();
    while(ch<0||ch>9){
        if(ch==-)f=-1;
        ch=getchar();
    }
    while(ch>=0&&ch<=9){
        res=res*10+(ch-0);
        ch=getchar();
    }
    return res*f;
}
int x,n,a[9999],sum,ans;
int main(){
    x=read();n=read();
    for(int i=1;i<=n;++i){
        a[i]=read();
    }
    sort(a+1,a+n+1);
    if(a[1]!=1){
        cout<<"-1";
        return 0;
    }
    while(sum<x){
        int i;
        for(i=n;i>=1;i--)   
            if(a[i]<=sum+1)break;
        ans++;
        sum+=a[i];
    }
    cout<<ans;
}

 

以上是关于[Luogu P1658] 购物的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P1450 [HAOI2008]硬币购物

[Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

LUOGU 2792: [JSOI2008]小店购物 最小树形图

Luogu2792 JSOI2008 小店购物 最小树形图

Vue实现购物小球抛物线的方法实例

HAOI2008硬币购物