zoukankan      html  css  js  c++  java
  • HZOJ Blue

    Blue:

    贪心。

    我们不妨给蛤定一个先后顺序,则贪心策略即从右至左每只蛤依次往最远的石子跳。

    证明:

    如果最右的蛤不往最远的石子跳,而是选择了一个较近的石子,那么必然会存在一个该蛤左边的蛤越过了它跳向其右边。因为每个蛤的能力是相同的,我们可以交换路线使得该贪心策略不变差。

    接着用归纳法可以证明对于所有蛤该策略最优。

    复杂度O( N )

    各种大佬用各种方法A了这道题……ooo的sb线段树,什么set,队列啥的都用上了……貌似只有我和b哥打了网络流,(B神盖世)比我厉害用了线段树优化建边+网络流,复杂度什么都好像都说的过去,而我只是冲着那30分去的。

    网络流就比较好想了,建立两个超级源点S,SS,S向SS连容量为m的边,将每个石头拆开,连容量为1的边(如果每个石头可以跳k次那网络流板erb正解),然后相距不超过d的石头连边,最大流就是答案,不过复杂度好像说不过去……

    正解:

    将所有的蛤(不是青蛙吗???)看作一个整体,那么每次跳都会占据一段石头,这样是最优的,而且每次青蛙都会尽量向远处跳,所以我么可以得到这样一个结论:若一只蛤在i,下次跳最远能到j,那么最多会剩下j-i+1只蛤(即把之间全占满),这样取符合条件最大值就是了。可以用单调指针实现。

     1 #include<iostream>
     2 #include<cstdio>
     3 #define LL long long
     4 #define ma(x) memset(x,0,sizeof(x))
     5 using namespace std;
     6 int T,n,m,d,l,a[1000010];
     7 signed main()
     8 {
     9     cin>>T;
    10     while(T--)
    11     {    
    12         cin>>n>>m>>d>>l;
    13         for(int i=1;i<=n;i++)cin>>a[i];
    14         if(d==l){puts("Excited");continue;}
    15         int ans=m;a[n+1]=l;
    16         int R=0;bool pd=0;
    17         for(int i=0;i<=n+1;i++)
    18         {
    19             while(a[R+1]-a[i]<=d&&R<n+1)R++;
    20             if(R==n+1)break;
    21             ans=min(ans,R-i);
    22         }
    23         if(ans==m)puts("Excited");
    24         else cout<<ans<<endl;
    25     }
    26 }
    和Dinic比起来短好多……
  • 相关阅读:
    各种有趣言论收集
    人类未来进化方向恶考
    mysql 列所有表行数
    恩,有那么一个人
    00后厉害哇
    。。。。
    放弃微博,继续回来写月经
    嘿,大家还好吗
    git
    require js
  • 原文地址:https://www.cnblogs.com/Al-Ca/p/11331094.html
Copyright © 2011-2022 走看看