• 20171013 am


    T1,是个二分,不过我二分的是前几个时刻上山,然后就因为每次最多但不一定走d的距离,然后处理起来就有很多的细节,然后不放心,弄了个暴力拍了半天,搞了大概40min,正解是直接二分答案,然后判断上山的时间加上下上的时间是不是小于n-1就行了,简单清新:

    T2,主要不好处理的就是如何找到最大值为K的集合有多少个,其实就是找到每一个数K左边的一个>K的位置l,然后找到右边第一个>=K的数的位置r,(一边取等一边不取能保证集合不重复),然后这个数为最大值的贡献就是(pos[i]-l+1)*(r-pos[i]+1);

    然后我就用了个分块,虽然最后的时间不慢,但是打起来还是有比较多的细节,正解是直接用单调队列,然后正反两边就能O(n)的处理出需要的两个位置,例如正向的时候可以维护一个单减的队列,然后每次插入的时候,就可以找到前面第一个比他大的;

    T3的话,超哥打表找规律过了,hww也找到了O(n)的正解,其实在做最后一道题的时候还剩下1.5h,但是没有理解题目中的排序方法,也没有看到给的E(4)的提示,然后就硬搞了35min的样例,虽然之前审题很小心,可能是因为觉得这个题不好做,然后就没什么耐心了,这种题一看就是打表找规律;那么现在就理解一下题解的规律:

    设法f[i]就是题目中的分子

    首先f[1]肯定是0;

    然后我们可以考虑f[i]与f[i-1]的关系,假设先排i个数中的i-1个,那么显然需要的步数就是f[i-1];

    那么我们就可以枚举最后一位是什么,

    先结论: 最后一位为i的时候,步数就是f[i-1](不用有多余的移动),其余情况的步数为f[i-1]+(i-1)! *2^(i-1);

    设最后一位为k;

    k=1时,也就是说之前所有的排列情况的步数都要+1,所以新增的贡献就是 (i-1)! *1;

    k=2时,要先把2移到最前变成 21.然后再动1,新增的贡献就是 (i-1)! *2;

    k=3时,从这里就可以找到规律了,先一步变为 312,然后这个时候要把1移到最前面,实际上和k==1的时候的方案数是一样的,然后变成了 132,又可以发现,这里把2一道最前面的步数和k==2时是一样的;

    那么可以得到规律,把i移到最前面时,新增的步数就是1+之前所有的步数(2^i(i-1) - 1),然后再加上自己的一步刚好就是2^(i-1);

    然后整理一下式子,用一下等比数列求和就能得到O(n)的递推公式 f[i]= i * f[i-1] + (2^(i-1) - 1) * (i-1)!;

  • 相关阅读:
    C# 注册表操作类
    NVelocity for AS“.NET研究”P.NET MVC 狼人:
    C#4.0新特性"协变"“.NET研究”与"逆变"以及背后的编程思想 狼人:
    原创“.NET研究”企业级控件库之图片浏览控件 狼人:
    “.NET研究”关于C# 中的Attribute 特性 狼人:
    如何让ASP.NET默认的资源编程“.NET研究”方式支持非.ResX资源存储 狼人:
    使用 “.NET研究”IIS Express 取代 ASP.NET Development Server 狼人:
    云计算从基础到应用架“.NET研究”构系列云计算的演进 狼人:
    通过自定义配置实现插“.NET研究”件式设计 狼人:
    ASP.NET MVC 3 概述“.NET研究” 狼人:
  • 原文地址:https://www.cnblogs.com/FOXYY/p/7660539.html
Copyright © 2020-2023  润新知