zoukankan      html  css  js  c++  java
  • 洛谷

    为了凑出 1 - x 的所有硬币:

    假设当前已经凑出了1 ~ m 的所有面值的硬币,那么为了凑出更大面值的硬币,应该如何选择呢?

    有这些情况:

    <1> 选面值 t 属于 1~m  的硬币:

    这当然可以,但是想一想,有没有更好的选择呢?

    我们选择一个面值为 t 的硬币,那么,我们下一次能够凑出的面值为 1 ~ m + t

    为了符合题意、凑出所有1 ~ x 的硬币,我们当然希望这个 m + t  越大越好!

    那么,就要求我们这一次选择的 t 越大越好。

    因此: 我们可能需要再 1 ~ m中选一个价值最大的硬币。

    <2> 选面值 t 属于 m+1 ~ ? 的硬币:

    假设选择面值是 t + 1的,这符合题意吗? 

    想一想: 原本凑出了1~m,这一次得到了m+1,那么我们就得到了从 1 ~ 2m + 1的所有面值的硬币。这说明选1 + m是可以的

    那么,还能继续变大吗?

    比如 选 m+2 ?

    显然不行,如果选择了m+2,那么我们就没有办法凑出面值为 m + 1的硬币了(想一想,原本凑出的是1~m的硬币,这一次选了个m+2的硬币,那么我们能凑出的

    硬币的区间实际上是不连续的 ,它是 [1 , m]  U [m+2,2m+2] ,漏掉了 m+1 。 )

    因此,可以确定贪心的方法: 每一次从所有面值中选择一个面值 t 属于 [1,m+1] 的、且最大面值的硬币。

    就可以得到最优解

     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 int arr[20];
     5 int main(){
     6     int x,n;
     7     cin >> x >> n;
     8     for(int i = 0; i < n; i++){
     9         cin >> arr[i];
    10     }
    11     sort(arr,arr+n);
    12     
    13     int m = 0;
    14     int cnt = 0;
    15     while(m < x){
    16         for(int j = n-1; j >= 0; j--){
    17             if(arr[j] <= m+1){
    18                 cnt++;
    19                 m += arr[j];
    20                 break;
    21             }
    22         }
    23     }
    24     if(cnt == 0 && x != 0)
    25         cout<<"-1";
    26     else cout<<cnt;
    27     return 0;
    28 }
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    Silverlight Binding之ConverterParameter
    .Net 深克隆与浅克隆实践笔记
    oracle中的锁机制
    .Net生成GUID号
    微软经典面试题之一——16个硬币问题
    C# string.Format 与+性能比较
    c#实现最简快速排序,你绝对可以看懂
    hdu 1204 糖果大战
    hdu 1166 敌兵布阵
    nyoj 7 喷水装置一
  • 原文地址:https://www.cnblogs.com/popodynasty/p/12193903.html
Copyright © 2011-2022 走看看