P1658 购物

https://www.luogu.com.cn/problem/P1658
涉及知识点:贪心
黄色题

思路:

道题的解法可能比较单一吧,然后我看了一下下面的题解,有一些不是那么好懂,说的不是特别特别透,或许我举个例子更多人可以看懂。

我们要明确以下几点:

  1. 如果我们的给定面值里没有1,那么肯定无解,为什么呢,首先我们就没有办法凑出1来。如果有1呢,只要我们舍得带很多硬币,肯定可以凑出任意面值。
  2. 我们假设现在我们手中的面值已经可以凑出11~HH中的所有面值,这个时候,我们要想一想,我们现在再准备带的这个硬币,应该满足什么样的条件呢?现在举一个例子。我们手里现在有面值和为5的硬币,并且可以凑出从11~55的所有面值。现在,
如果我们选 则可以凑出 1 1,2,3,4,5,6 2 1,2,3,4,5,6,7 3 1,2,3,4,5,6,7,8 4 1,2,3,4,5,6,7,8,9 5 1,2,3,4,5,6,7,8,9,10 6 1,2,3,4,5,6,7,8,9,10,11 选一个解释:如果我们选4,那我们肯定可以凑出1~5(之前就可以凑出 来),对于6,我们可以用之前凑出来的2加上现在选的4,对于7,我们可以 用之前凑出来的3加上现在选的4,以此类推,但是10我们就不能凑出来了。 然后,如果我们选择7,同理可以凑出来1~5,然后6呢,我们选之前凑不出 来,用现在选的7加上“没有”、“1”、“2”、“3”、“4”、“5”都不 可能凑出来,因为7+0就已经大于6了,再加什么也不可能等于6。你也可以 再去自己算一下其他的例子,会发现,当且仅当我们选的数不大于当前选的 面值的和+1,我们可以保证凑出连续的面值(不要想去跳着凑面值,不可能 的)。 然后我们发现,我们选的数越大,他可以凑出来的面值就越多,我们就尽可 能的选给我们的面值里面,满足不大于面值和+1的最大面值,这样,我们带 去购物且满足可以凑出1~X中所有面值的硬币数会更少,答案就更小。
复制代码
#include<iostream> #include<algorithm> using namespace std; int a[1005]; bool cmp(int p,int q){ return p>q; }//尽量选大的才能保证答案最小 int main() { int X,n,ans=0,SUM=0; cin>>X>>n; for(int i=1;i<=n;i++)cin>>a[i]; sort(a+1,a+n+1,cmp); if(a[n]!=1){//我们说过了,无解的情况 cout<<-1<<endl; return 0; } while(SUM<X){//如果我们现在还不能凑出1~X的所有面值,那就要再选 for(int i=1;i<=n;i++) if(a[i]<=SUM+1){ SUM+=a[i]; break; } ans++;//又选了一张 } cout<<ans<<endl; return 0; }
复制代码

 


__EOF__

本文作者灰の魔女伊蕾娜
本文链接https://www.cnblogs.com/2elaina/p/16481631.html
关于博主:编程小萌新一名,希望从今天开始慢慢提高,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   -イレイナ  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示