zoukankan      html  css  js  c++  java
  • coin collector(一道测试题)

    题目(后面有中文大意)

    Our dear Sultan is visiting a country where there are n different types of coin. He wants to collect as many different types of coin as you can. Now if he wants to withdraw X amount of money from a Bank, the Bank will give him this money using following algorithm.

    withdraw(X){

    if( X == 0) return;

    Let Y be the highest valued coin that does not exceed X.

    Give the customer Y valued coin.

    withdraw(X-Y);

    }

    Now Sultan can withdraw any amount of money from the Bank. He should maximize the number of different coins that he can collect in a single withdrawal.

    Input:

    First line of the input contains T the number of test cases. Each of the test cases starts with n (1≤n≤1000), the number of different types of coin. Next line contains n integers C1, C2, … , Cn the value of each coin type. C1< C2< C3< … < Cn<1000000000. C1 equals to 1.

    Output:

    For each test case output one line denoting the maximum number of coins that Sultan can collect in a single withdrawal. He can withdraw infinite amount of money from the Bank.

    Sample Input

    2

    6

    1 2 4 8 16 32

    6

    1 3 6 8 15 20

    Sample Output

    6

    4

    题目大意

    你要从银行取价值X的钱,有n种不同的硬币,银行给钱时会执行一个递归程序:
    取钱(X){
    if(X==0)return;
    给你<=X的最大硬币Y;
    取钱(X-Y);
    }
    你的目的是要取得硬币种类尽可能多,输入n(1<=n<=1000),和每种硬币的面值,输出最大种类数。

    题解

    思路:贪心
    首先,假设从1到i被选中的硬币的和是sum[i],第i个硬币的值是a[i],那么当sum[i]< a[i+1]的时候,就可以在保持原来选的同时,选上第i+1个。(证明:假设sum[i]>=a[i+1],那么要选,一开始的数字就是sum[i],而sum[i]>=a[i+1],那么就可以选一次i+1,然后剩下的数字就不够sum[i]了,无法选够原来的了,此时假设不成立,即sum[i]< a[j])
    由上述规律即可推出可以选一个数字i的两个条件:1.sum[i-1]< a[i];2.sum[i] (=sum[i-1]+a[i])< a[i+1];满足上述条件的情况下,就可以选这个数字了。
    还有,一定要选第一个和最后一个(一样可以用反证法证明)
    Then,注意要特判2以下的情况。
    最后还有一点小优化:这个递推过程是单向且线性的,那么sum数组就可以简单地用一个sum变量来代替了(不过说实话没什么大用)
    代码请参见文尾。


    说点儿题外话:我一开始想到的确实是这个思路,可是马上被推翻了,因为按以往经验普及最后一道题总是特别难,不可能这么简单,于是想了一个dp+二分查找,才算觉得够难度了,可是,结果10分,我的内心是崩溃的O_O,惨痛的教训就是永远不要想当然,也不要相信样例(我就是这个算法过了样例)


    还有,如果你是初一或初二,那么好好学oi吧,不要来机房混日子(我看见考试时有好几个人玩三维弹球,蜘蛛纸牌),来混日子还不如回去学文化课,还不如早日AFO(Away From OI)。不过,我还是认为这个行业是很有出路的。
    如果要学OI的话,就利用好寒假和暑假,平常缓慢学习,积累经验,假期做出质的突破。
    还有,不能眼高手低,不能遇难而退,不能半途而废。
    最后,祝好好学习OI的人取得NOIP普及组一等奖(看看你们有几个,当年就我一个)


    #include<bits/stdc++.h>
    using namespace std;
    int t,n,a[1005];
    
    int main(){
        //建议你们用scanf和printf,会快很多
        scanf("%d",&t);
        for(int i=1;i<=t;i++){
            scanf("%d",&n);
            for(int j=1;j<=n;j++){
                scanf("%d",&a[j]);
            }
            if(n<=2){//要特判2以下的情况
                printf("%d
    ",n);
                continue;
            } 
            int sum=a[1];
            int cnt=2;//Ñ¡µÚÒ»¸öºÍ×îºóÒ»¸ö 
            for(int i=2;i<=n-1;i++){
                if(sum<a[i]&&sum+a[i]<a[i+1]){
                    sum+=a[i];
                    cnt++;
                }
            }
            printf("%d
    ",cnt);
        }
        return 0;
    }
  • 相关阅读:
    Python之并发编程(三)生产者与消费者模型
    Python之并发编程(四)多线程(相关理论)
    cookiesession okenkey四大参数解析
    常见http返回的状态码
    for遍历用例数据时,报错:TypeError: list indices must be integers, not dict,'int' object is not iterable解决方法
    python中调用函数时,参数顺序与参数赋值问题
    自动化测试用例中的raise
    python --------简单的socket通话实现例子
    python---------------logging
    Monkey
  • 原文地址:https://www.cnblogs.com/stone41123/p/7581305.html
Copyright © 2011-2022 走看看