zoukankan      html  css  js  c++  java
  • Codeforces 834D

    834D - The Bakery

    思路:dp[i][j]表示到第j个数为止分成i段的最大总和值。

    dp[i][j]=max{dp[i-1][x]+c(x+1,j)(i-1≤x≤j-1)},c(x+1,j)表示x+1到j的不同的值。

    用线段树维护一下最大值。

    上图最后一个点取不到,不解释,不明白请评论。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define ls rt<<1,l,m
    #define rs rt<<1|1,m+1,r
    #define pb push_back 
    const int INF=0x3f3f3f3f;
    const int N=35555;
    int tree[4*N],lazy[4*N];
    int dp[55][N];
    int now[N],pre[N],a[N];
    int i;
    
    void push_up(int rt)
    {
        tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
    }
    
    void push_down(int rt)
    {
        tree[rt<<1]+=lazy[rt];
        lazy[rt<<1]+=lazy[rt];
        tree[rt<<1|1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        lazy[rt]=0;
    }
    
    void build(int rt,int l,int r)
    {
        if(l==r)
        {
            tree[rt]=dp[i-1][l];
            return ;
        }
        int m=(l+r)>>1;
        build(ls);
        build(rs);
        push_up(rt);
    }
    
    void update(int p,int delta,int rt,int l,int r)
    {
        if(l==r)
        {
            tree[rt]+=delta;
            return ;
        }
        int m=(l+r)>>1;
        if(p<=m)update(p,delta,ls);
        else update(p,delta,rs);
        push_up(rt);
    }
    
    void Update(int L,int R,int delta,int rt,int l,int r)
    {
        if(L<=l&&r<=R)
        {
            tree[rt]+=delta;
            lazy[rt]+=delta;
            return ;
        }
        if(lazy[rt])push_down(rt);
        int m=(l+r)>>1;
        if(L<=m)Update(L,R,delta,ls);
        if(R>m)Update(L,R,delta,rs);
        push_up(rt);
    }
    
    int query(int L,int R,int rt,int l,int r)
    {
        if(L<=l&&r<=R)return tree[rt];
        if(lazy[rt])push_down(rt);
        int m=(l+r)>>1,ans=0;
        if(L<=m)ans=max(ans,query(L,R,ls));
        if(R>m)ans=max(ans,query(L,R,rs));
        return ans; 
    }
    
    int main()
    {
        int n,k;
        while(~scanf("%d%d",&n,&k))
        {
            memset(now,0,sizeof(now));
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
                pre[i]=now[a[i]];
                now[a[i]]=i;
            }
            dp[1][1]=1;
            for(i=1;i<=k;i++)
            {
                memset(tree,0,sizeof(tree));
                memset(lazy,0,sizeof(lazy));
                build(1,0,n);
                for(int j=i;j<=n;j++)
                {
                    Update(pre[j],j-1,1,1,0,n);
                    dp[i][j]=query(i-1,j-1,1,0,n);
                }
            }
            cout<<dp[k][n]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET Boilerplate
    Financial.IPmt/Financial.PPmt
    VB内部函数(三)——财务函数
    Convert VB.NET to C#
    MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
    Oauth2.0客户端服务端示例
    一张图搞定OAuth2.0
    使用JAVA实现的一个简单IOC注入实例
    谈谈对Spring IOC的理解
    秒懂,Java 注解 (Annotation)你可以这样学
  • 原文地址:https://www.cnblogs.com/widsom/p/7275337.html
Copyright © 2011-2022 走看看