• 洛谷


    为了凑出 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 ----
  • 相关阅读:
    中国的南方人和北方人有什么区别?总算说透了!
    怎样通过穴位按摩来减轻脚踝扭伤的疼痛
    关于脚踝不得不说的各种事
    电影发烧友必备知识-720P、1080P、4K的区别
    有什么相见恨晚的小知识?
    男生有钱到底有多重要?
    es6学习笔记5--promise
    es6学习笔记4--数组
    js设计模式总结1
    es6学习笔记3--解构和对象
  • 原文地址:https://www.cnblogs.com/popodynasty/p/12193903.html
Copyright © 2020-2023  润新知