zoukankan      html  css  js  c++  java
  • BZOJ

    现在给你一个长度为n的整数序列,其中有一些数已经模糊不清了,现在请你任意确定这些整数的值,
    使得最长上升子序列最长。(为何最长呢?因为hxy向来对自己的rp很有信心)
     
    Input
    第一行一个正整数n
    接下来n行第i行格式如下
         K x:表示第i个数可以辨认且这个数为x
         N:表示第i个数一个已经辨认不清了
    (n<=100000,|x|<=10^9)
     
    Output
    一个正整数代表最长上升子序列最长是多少
     
    Sample Input
    4
    K 1
    N
    K 2
    K 3

    Sample Output

    题意:有一个序列,有些位置的数由你来决定,求LIS。

    思路:首先我们知道求LIS可以用二分来优化,那么我们维护一个上升的序列,用dp[i]表示长度为i的LIS的最后一位最小是多少,每次新加入一个数的时候,用x去替换upper_bound的位置即可。  

    然而这个题有未知数,未知数可以由自己决定,所以每个未知数都要使用比较优,对于每个dp[i],可以用dp[i]+1去更新dp[i+1],即右移一位,我们用add来表示。

    #include<bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=100010;
    int dp[maxn],add;
    int main()
    {
        dp[0]=-(1e9+10);
        int N,x,R=0; char c[4];
        scanf("%d",&N);
        rep(i,1,N){
            scanf("%s",c+1);
            if(c[1]=='K'){
                scanf("%d",&x);
                int l=0,r=R,pos,mid;
                while(l<=r){
                    mid=(l+r)>>1;
                    if(dp[mid]+add<x) { l=mid+1; pos=mid;}
                    else r=mid-1;
                }
                if(pos==R) dp[++R]=x-add;
                else dp[pos+1]=min(dp[pos+1],x-add);
            }
            else add++;
        }
        printf("%d
    ",R+add);
        return 0;
    }
  • 相关阅读:
    洛谷 P1550 [USACO08OCT]Watering Hole G(最小生成树||超级源点)
    洛谷 P2168 [NOI2015]荷马史诗(Huffman树|编码)
    洛谷 P5658 括号树(DFS)
    用堆来求中位数
    c++各种输入输出(文件输入输出,标准输入输出,一些字符串)
    Hello,world!
    【NOIP2013】花匠
    【洛谷习题】最长上升子序列
    【NOIP2014】联合权值
    【NOIP2014】飞扬的小鸟
  • 原文地址:https://www.cnblogs.com/hua-dong/p/9883673.html
Copyright © 2011-2022 走看看