zoukankan      html  css  js  c++  java
  • 夏令营

    夏令营

    (camp.pas/c/cpp) 128MB 2s

    Nano想靠刷题来增长实力,于是她从题库中找到了n道题打算在夏令营的时候全部刷掉。她计划按题号顺序一道一道刷。n道题中有DP,有贪心,有图论,也有模拟……各种各样的类型都有。夏令营有k天,她想合理安排每天的刷题量,使得每天能刷到尽量多种类型的题。设第i天刷了Ai种类型的题目,问要怎么安排,才能安排全部题都刷完,而且这k天的Ai的和最大。

    输入格式

    1行为两个正整数 n和k,为题数和夏令营天数。

    2行N个数,第i个数Ci表示第i题的类型。

    输出格式

    仅一行一个数,表示最优方案下,这k天的Ai的和的最大值。

    样例输入

    8 3
    7 7 8 7 7 8 1 7

    样例输出

    6

    样例解释

    第一天做前三题,第二天做第4至第6题,剩余的两题第三天做。这样安排的话每天都能做到两种类型的题,加起来为6.

    这道题很容易想到O(nnk)的dpQAQ

    但是正解需要线段树优化一波 

    操作有区间求max和区间加

    区间加的范围就是当前点到他颜色出现的前一次的位置

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    #define LL long long
    using namespace std;
    const int M=45007,N=1<<17; 
    int read()
    {
        char c;int s=0,t=1;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    int T,n,m,c[M],cnt,L,R;
    int f[M],last[M];
    struct node{int v,pos;}e[M];
    struct note{int h,mx;}tr[N];
    bool cmp(node a,node b){return a.v<b.v;}
    int max(int a,int b){return a>b?a:b;}
    inline void up(int x){tr[x].mx=max(tr[x<<1].mx,tr[x<<1^1].mx);}
    void build(int x,int l,int r){
        tr[x].h=0;
        if(l==r){
            tr[x].mx=f[l-1];
            return ;
        }
        int mid=(l+r)>>1;
        build(x<<1,l,mid);
        build(x<<1^1,mid+1,r);
        up(x);
    }
    void modify(int x,int l,int r){
        note&w=tr[x];
        if(L<=l&&r<=R){
            ++w.mx;
            ++w.h;
            return ;
        }
        note&lc=tr[x<<1],&rc=tr[x<<1^1];
        if(w.h){
            int a=w.h;
            lc.mx+=a;
            lc.h+=a;
            rc.mx+=a;
            rc.h+=a;
            w.h=0;
        }
        int mid=(l+r)>>1;
        if(L<=mid) modify(x<<1,l,mid);
        if(R>mid) modify(x<<1^1,mid+1,r);
        w.mx=max(lc.mx,rc.mx);
    }
    void push_max(int x,int l,int r){
        note&w=tr[x];
        if(w.mx<=T) return ;
        if(L<=l&&r<=R) return void(T=w.mx);
        if(w.h){
            note&lc=tr[x<<1],&rc=tr[x<<1^1];
            int a=w.h;
            lc.mx+=a;
            lc.h+=a;
            rc.mx+=a;
            rc.h+=a;
            w.h=0;
        }
        int mid=(l+r)>>1,ans=0;
        if(L<=mid) push_max(x<<1,l,mid);
        if(R>mid)  push_max(x<<1^1,mid+1,r);
    }
    int main()
    {
        freopen("camp.in","r",stdin);
        freopen("camp.out","w",stdout);
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++) e[i].v=read(),e[i].pos=i;
        sort(e+1,e+1+n,cmp);
        c[e[1].pos]=++cnt;
        for(int i=2;i<=n;i++){
            if(e[i].v!=e[i-1].v) cnt++;
            c[e[i].pos]=cnt;
        }
        for(int k=1;k<=m;k++){
            build(1,1,n);
            memset(last,0,sizeof(last));
            for(int i=1;i<=n;i++){
                L=last[c[i]]+1; R=i;
                modify(1,1,n);
                L=1; R=i;
                T=0;
                push_max(1,1,n);
                f[i]=T;
                last[c[i]]=i;
            }
        }printf("%d
    ",f[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    json取值(key是中文或者数字)方式详解
    快速排序
    百度地图 获取矩形point
    ArcGIS
    天眼
    shapefile文件
    SQL Server 2008 的gis函数
    查看某一个点是否在某个多边形内 使用ST_Contains函数
    PostgreSQL+PostGIS的使用 函数清单
    地理坐标计算
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7343822.html
Copyright © 2011-2022 走看看