zoukankan      html  css  js  c++  java
  • [bzoj4282]慎二的随机数列_动态规划_贪心

    慎二的随机数列 bzoj-4282

    题目大意:一个序列,序列上有一些数是给定的,而有一些位置上的数可以任意选择。问最长上升子序列。

    注释:$1le nle 10^5$。


    想法:结论:逢N必选。N是可以任意选择的位置。

    具体的,我们将所有N踢出序列,将给定的权值-=前面N的个数。再在当前序列上求最长上升子序列。

    正确性的话如果当前序列中的数:

    如果前面的数小于后面的数,显然中间的N我也可以加上。

    如果前面的数大于后面的数:

      如果前面的数在原序列中的权值大于后面的数在原序列中的权值,那么这两个数无论如何都不能同时选择。

      而如果前面的数在原序列中的数小于后面的数在原序列中的权值,那么我们选择抛弃后面的数转而选择中间的所有N,显然更优。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 100010 
    using namespace std;
    int dp[N],sum,a[N],cnt;
    int q[N];
    int maxn=0;
    int main()
    {
        int n; cin >> n ;
        char opt[10];
        for(int i=1;i<=n;i++)
        {
            scanf("%s",opt+1);
            if(opt[1]=='K')
            {
                int x; scanf("%d",&x);
                x-=sum;
                a[++cnt]=x;
            }
            else sum++;
        }
        int ans=0;
        for(int i=1;i<=cnt;i++)
        {
            int l=0,r=ans;
            while(l!=r)
            {
                int mid=(l+r+1)>>1;
                if(a[q[mid]]<a[i]) l=mid;
                else r=mid-1;
            }
            l++;
            ans=max(ans,l);
            q[l]=i;
        }
        printf("%d
    ",ans+sum);
    }
    

    小结:这题...不禁让我想到了Claris的CDQ分治+扫描线+树状数组...

    证明对于计算机竞赛的用处,就是可以简化一个复杂的算法(个人理解)。

  • 相关阅读:
    Android 布局中 如何使控件居中
    VGA, QVGA, HVGA, WVGA, FWVGA和iPhone显示分辨率
    [转+整理] Android 分辨率,密度,像素单位说明
    多线程的知识点总结
    集合的相关信息
    spring cloud详解
    iostat实时监控磁盘util
    Jenkins安装过程
    hdfs的block为什么设置成128M
    shell变量自增的几种方式
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9537849.html
Copyright © 2011-2022 走看看