zoukankan      html  css  js  c++  java
  • Blue:贪心,单调队列

    考场上什么都没想。

    显然在扯淡了,应该说是刚开始想了一些没用的。

    有决策单调性,所以二分答案?

    好,那就二分答案。想想怎么检查每只蛤能不能都跳到终点?

    那么每只蛤都不能掉队啊。

    如果你现在遇到了一个石头,你就会优先让最落后的那只蛤跳过来蛤。(因为都不能掉队啊)

    如果它离的太远跳不过来了,那么这只蛤就永远地掉队了。

    嗯,这个想法还是比较简单的吧。

    然后我们可以发现这个思路貌似是普适的。我们现在去掉二分答案。

    所以现在问题不再是检查是否都不掉队,而是直接询问有多少个蛤能过去。

    继续上面的思路,让最落后的蛤尝试跳过来,跳不过来就放弃它去让第二落后的蛤来。

    然后有了这个思路就可以愉快的AC了。

    当然我们需要证明(我没看题解,我自己口胡蛤)

    对于任意多的蛤,分别标号为1234...,按照它们目前所在的位置排序

    那么现在突然出现了一个石头用0表示:1234...0

    现在要用蛤来跳,按照刚才的策略你会让1跳得到234...1

    其它决策无非就2种,

    一种是这块石头所有蛤都无视它:这一定不优,如果你要忽视它还要跳到后面,那么你在这里歇一下脚再往后跳当然不会变差啦

    另一种就是让不是最落后的蛤跳到上面:你会得到12x4...3之类的(x表示被踩沉了的石头)

    相较于最优决策,区别就是有一只还在原来的最落后位置,而最优决策下有一只蛤更靠前了一点(至少不再是那个最落后位置了)

    而还在最落后位置上的那只蛤可能从此就掉队了,故这个决策不优。

    所以维护一个队列,表示目前还没有被放弃的蛤的位置。

    枚举每块石头,让队首的蛤不能跳就放弃,能跳就跳,把它从队首改变位置放到队尾。

    因为石头已经排序,所以加入队尾的元素一定是递增的,所以队列自带单调。

    所有的石头都跳完之后,队列里的蛤不能跳到终点的就放弃。

    最后队列里有几个蛤就是几啦。

    多测清空!蛤的初始位置重置为0!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,d,l,x[1000005],q[2000005],t,h,T;
     4 int main(){//freopen("blue.in","r",stdin);
     5     scanf("%d",&T);
     6     while(T--){
     7         scanf("%d%d%d%d",&n,&m,&d,&l);
     8         for(int i=1;i<=n;++i)scanf("%d",&x[i]);
     9         h=1;t=m;for(int i=1;i<=m;++i)q[i]=0;
    10         for(int i=1;i<=n;++i){
    11             while(q[h]+d<x[i]&&h<=t)++h;
    12             ++h;q[++t]=x[i];
    13         }
    14         while(q[h]+d<l&&h<=t)h++;
    15         if(t-h==m-1)puts("Excited");
    16         else printf("%d
    ",t-h+1);
    17     }
    18 }
    代码复杂度:462B
  • 相关阅读:
    奥巴马邻居卖房的启示,彻底改变你的思维!
    CentOS7.0安装Nginx 1.7.4
    CentOS 7 下安装 Nginx
    C# 关于线程锁lock的使用方法
    内存屏障、编译屏障:
    linux环境下安装nginx步骤
    一、为什么要学习Java虚拟机?
    Linux CentOS系统上安装Eclipse
    poj 3311 Hie with the Pie (TSP问题)
    怎样初始化一个指针数组
  • 原文地址:https://www.cnblogs.com/hzoi-DeepinC/p/11331079.html
Copyright © 2011-2022 走看看