• 2014 3.22 校队选拔——A


    依然非常失望,我为什么现在还是那么弱,今天就做出了一道题,垫底。

    一个大家都看出来的C题,我居然没找到规律,想了一会儿就放弃了。

    A题是这样的,有n种珍珠,给出这n种珍珠各自的数目,再给出一个M,表示每M个不同珍珠组成一个项链。求问最多可以组成多少个这样的项链。

    一开始想到的就是贪心,发现如果按升序排序,再从前往后去贪心,样例都过不了,如果从后往前贪,可以过样例,而且感觉好像没有什么不妥,于是就造就了今天的一直WA的情况。这个题目不能用贪心,从前往后贪的时候就发现有问题,即,某个珍珠可以此时用完,但如果等下一次跟后面一个数用完的话,得到的总数将会更大。。。其实同理,由后往前贪也会出现这种情况,只是恰好过了样例而已。

    真正标准的做法是二分结果,其实当时我也有考虑这样,但是那个时候不知道怎么判断你二分的结果是对还是错,我当时想,如果能够判断你二分的结果是大于最终值还是小于的话,应该可以直接暴力过啊。。。所以就一直没付诸行动,一直到最后几分钟,我还是觉得自己是贪心没写的好,一直在那里改代码,也有想过是不是算法本身的问题,要不要用贪心来写一下,但是就这样想了一下,没时间了

    其实难就难在你怎么知道你二分的这个结果是合理的,比如你二分的结果是4,设M=5,那总共需要的珍珠数就是4*5=20,这二十颗从哪里来呢,我们来想一下,如果正好每种珍珠只有一颗,那总共需要20种珍珠才行,但是若每种珍珠无限多,那就是每种取4个,取五种,凑成这20颗。也就是说,我们每次枚举出来的值,作为每种珍珠的取用上限,(当然珍珠数本身不够这个上限就按自身的数目来取),从序列里按这个上限从头取到尾,如果能凑齐大于等于 枚举值*M,说明该枚举值可行。。。这是陶叔比赛完之后跟我讲的,我当时没理解,为什么这么搞可以判断枚举值是否可行呢,后来仔细想了下,尤其考虑了一下临界情况(即上述说的每种珍珠只有一颗 或者 每种珍珠无限多)才理解这个做法,因为每次取的珍珠不超过枚举值(超过了其实没用,每种珍珠最多只要枚举值那么多颗,而且影响判断),这样,这样取出的珍珠数目其实就暗藏了各个这么多个组合,比如你取的数目不够,则它能凑齐的项链组合 是实际值-1甚至更小,如果数目够了,则能凑的项链组合就是实际值甚至更多。

    所以,解决了这个判断问题,就比较简单了

    具体题解看 http://hi.baidu.com/congzicun/item/c1bcb4f7c2cf6acc521c264f

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m;
    int num[1010];
    bool ok(int x)
    {
        int sum=0;
        for (int i=0;i<n;i++)
        {
            if (num[i]<x)
                sum+=num[i];
            else
                sum+=x;
        }
        if (sum>=x*m) return 1;
        else  return 0;
    }
    int main()
    {
        while (scanf("%d",&n))
        {
            if (n==0) break;
            int maxn=0;
            for (int i=0;i<n;i++)
            {
                scanf("%d",&num[i]);
                maxn=max(maxn,num[i]);
            }
            scanf("%d",&m);
            int l=0,r=(n/m)*maxn,mid;
            int ans=0;
            r++;
            while (l<r)
            {
                mid=(l+r)/2;
                if (ok(mid))
                {
                    ans=mid;
                    l=mid+1;
                }
                else
                    r=mid;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Mysql 分页查询sql优化
    观察者模式之spring事件机制
    封装一个按Key排序的Map工具
    SpringBoot java配置类@Configuration 的两种写法
    最基础前端路由实现,事件popstate使用
    mybatis分页插件PageHelper源码浅析
    看看线程特有对象ThreadLocal
    svn提交错误:Commit failed (details follow): Can't create directory
    mac下修复exfat格式外置硬盘
    [twisted] Multiple users
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3618011.html
Copyright © 2020-2023  润新知