zoukankan      html  css  js  c++  java
  • 选择客栈 递推

    写题思路一定要清晰后再动键盘,否则肯定死得很惨。。(被绿题虐系列

    题目要求所有满足颜色相同且两点间存在一点小于等于某值的方案数。

    显然2e6的数据一般是O(n)的做法,所以从一开始就在想递推式,然后由于思路比较乱,一直没有写出来,直到今天才好好理了理思路:

    对于读入到的一点,颜色为cl,价格为wi,对价格进行分类讨论:

    如果价格符合要求,那么该点前的所有点与该点及该点后点的连线都可以利用这一点,所以跨越该点的连线都是合法的。所以答案应加上这一点之前所有的同色点数。

    如果价格不符合要求,那么该点只能利用之前的合法点与前面的同色点连线,这样对答案的贡献就是之前所有在最后一个合法点之前的同色点数目。

    发现如果每加入一个合法点时都立即更新每种颜色的合法值所需要的时间复杂度为O(k),不符合要求,所以想到可以借助懒标记思想仅仅记录最后一个合法点的位置和每种颜色最后一个不合法点的位置,在查询到某种颜色时在进行更新即若该颜色最后一个不合法点的位置小于等于最后一个合法点的位置则把这些不合法点数加入合法点数中,这样就可以避免了大量的无用计算.

    code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #define rep(i,a,n) for(register int i = a;i <= n;++i) 
     4 using namespace std;
     5 
     6 int read(){int x;scanf("%d",&x);return x;}
     7 
     8 const int Maxk = 510;
     9 int cn1[Maxk],cn2[Maxk],la[Maxk];
    10 int ans,cl,wi,n,p,k;
    11 
    12 int main(){
    13     n = read(),k = read(),p = read();
    14     
    15     rep(i,1,n){
    16         cl = read(),wi = read();
    17         if(wi <= p){
    18             cn1[cl] += cn2[cl],cn2[cl] = 0;
    19             ans += cn1[cl];
    20             cn1[cl]++;
    21             la[k] = i;
    22         }
    23         else{
    24             if(la[cl] < la[k]){
    25                 cn1[cl] += cn2[cl];
    26                 cn2[cl] = 0;
    27             }
    28             cn2[cl]++,la[cl] = i;
    29             ans += cn1[cl];
    30         }
    31     }
    32     
    33     cout << ans;
    34 return 0;
    35 }
  • 相关阅读:
    2013Esri全球用户大会之ArcGIS for Desktop
    简单的session共享的封装
    支付系统开发中可能遇到的问题
    Java定位CPU使用高问题--转载
    ReflectionToStringBuilder
    solrcloud使用中遇到的问题及解决方式
    使用ELK(Elasticsearch + Logstash + Kibana) 搭建日志集中分析平台实践--转载
    php和java的memcached使用的兼容性问题解决过程
    multi-CPU, multi-core and hyper-thread--转
    Java Garbage Collection Basics--转载
  • 原文地址:https://www.cnblogs.com/Wangsheng5/p/11862597.html
Copyright © 2011-2022 走看看