• [SCOI2014]方伯伯的玉米田


    Description

    方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美。
    这排玉米一共有N株,它们的高度参差不齐。
    方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感的玉米拔除掉,使得剩下的玉米的高度构成一个单调不下降序列。
    方伯伯可以选择一个区间,把这个区间的玉米全部拔高1单位高度,他可以进行最多K次这样的操作。拔玉米则可以随意选择一个集合的玉米拔掉。
    问能最多剩多少株玉米,来构成一排美丽的玉米。

    Input


    第1行包含2个整数n,K,分别表示这排玉米的数目以及最多可进行多少次操作。
    第2行包含n个整数,第i个数表示这排玉米,从左到右第i株玉米的高度ai。

    Output


    输出1个整数,最多剩下的玉米数。

    Sample Input

    3 1
    2 1 3

    Sample Output

    3

    HINT

    1 < N < 10000,1 < K ≤ 500,1 ≤ ai ≤5000

    时限3S

    NK复杂度才5e6,3s时限,可以带两个log

    序列区间问题又比较容易带log

     

    考虑什么时候要拔高。

    一定是比前面矮,然后让它们长高一点。但是显然不要变得比后面高。

    所以,每次拔高的操作区间的右端点都是n!

    否则,右端点右面的部分只会贡献减少。

    然后就比较容易了。

    f[i][k]表示,前i个,以i结尾,包括i,一共拔高k次。

    转移:f[i][k]=max(f[j][l])+1 (j<i&&l<=k&&a[i]+k>=a[j]+l)

    j<i通过顺序可以保证。另外两个?
    a[i]只有5000,k只有500

    而且是一个二维前缀max

    所以二维树状数组即可。

     

    (注意,不一定以n结尾。所以是所有的f[i][k]取max)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=10000+5;
    const int M=505;
    int n,m;
    int t[5500+5][505];
    int a[N];
    int mx;
    void upda(int x,int y,int c){
        while(x<=mx){
            int p=y;
            while(p<=m+1){
                t[x][p]=max(t[x][p],c);
                p+=p&(-p);
            }
            x+=x&(-x);
        }
    }
    int query(int x,int y){
        int ret=0;
        while(x){
            int p=y;
            while(p){
                ret=max(ret,t[x][p]);
                p-=p&(-p);
            }
            x-=x&(-x);
        }
        return ret;
    }
    int f[N][M];
    int up[N];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),mx=max(mx,a[i]+m);
        int ans=0;
        for(int i=1;i<=n;i++){
            int tmp=0;
            for(int k=0;k<=m;k++){
                f[i][k]=query(a[i]+k,k+1)+1;
                ans=max(ans,f[i][k]);
            }
            for(int k=0;k<=m;k++){
                upda(a[i]+k,k+1,f[i][k]);
            }
        }
        for(int k=0;k<=m;k++) ans=max(ans,f[n][k]);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Qt 模拟一个导航定位系统
    【编程之美】用C语言实现状态机(实用)
    代码面试之链表
    乾坤合一~Linux设备驱动之USB主机和设备驱动
    乾坤合一~Linux设备驱动之I2C核心、总线以及设备驱动
    乾坤合一~Linux设备驱动之终端设备驱动
    乾坤合一~Linux设备驱动之块设备驱动
    蜕变成蝶~Linux设备驱动之watchdog设备驱动
    蜕变成蝶~Linux设备驱动之按键设备驱动
    蜕变成蝶~Linux设备驱动之DMA
  • 原文地址:https://www.cnblogs.com/Miracevin/p/9850508.html
Copyright © 2020-2023  润新知