zoukankan      html  css  js  c++  java
  • Codeforces Round #426 (Div. 2) D. The Bakery(线段树维护dp)

    题目链接: Codeforces Round #426 (Div. 2) D. The Bakery

    题意:

    给你n个数,划分为k段,每段的价值为这一段不同的数的个数,问如何划分,使得价值最大。

    题解:

    考虑dp[i][j]表示划分为前j个数划分为i段的最大价值,那么这就是一个n*n*k的dp,

    考虑转移方程dp[i][j]=max{dp[i][k]+val[k+1][j]},我们用线段树去维护这个max,线段树上每个节点维护的值是dp[i][k]+val[k+1][j],对于每加进来的一个数a[j],他只会影响last[a[j]]~j-1这段区间,所以线段树将这段区间加1。dp[i][j]就是区间最大值。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
     3 inline int RT(int l,int r){return l+r|l!=r;}
     4 using namespace std;
     5 
     6 const int N=40000;
     7 int n,k,mx[N*2],lazy[N*2],dp[N],a[N],la[N],pos[N];
     8 
     9 void build(int l=0,int r=n)
    10 {
    11     int rt=RT(l,r),mid=l+r>>1;lazy[rt]=0;
    12     if(l==r){mx[rt]=dp[l];return;}
    13     build(l,mid),build(mid+1,r);
    14     mx[rt]=max(mx[RT(l,mid)],mx[RT(mid+1,r)]);
    15 }
    16 
    17 void PD(int l,int r)
    18 {
    19     int rt=RT(l,r),ls=RT(l,l+r>>1),rs=RT((l+r>>1)+1,r);
    20     lazy[ls]+=lazy[rt],lazy[rs]+=lazy[rt];
    21     mx[ls]+=lazy[rt],mx[rs]+=lazy[rt];
    22     lazy[rt]=0;
    23 }
    24 
    25 void update(int L,int R,int v,int l=0,int r=n)
    26 {
    27     int rt=RT(l,r),mid=l+r>>1;
    28     if(L<=l&&r<=R){mx[rt]+=v,lazy[rt]+=v;return;}
    29     if(lazy[rt])PD(l,r);
    30     if(L<=mid)update(L,R,v,l,mid);
    31     if(R>mid)update(L,R,v,mid+1,r);
    32     mx[rt]=max(mx[RT(l,mid)],mx[RT(mid+1,r)]);
    33 }
    34 
    35 int ask(int L,int R,int l=0,int r=n)
    36 {
    37     int rt=RT(l,r),mid=l+r>>1,ans=0;
    38     if(L<=l&&r<=R)return mx[rt];
    39     if(lazy[rt])PD(l,r);
    40     if(L<=mid)ans=max(ans,ask(L,R,l,mid));
    41     if(R>mid)ans=max(ans,ask(L,R,mid+1,r));
    42     return ans;
    43 }
    44 
    45 int main(){
    46     scanf("%d%d",&n,&k);
    47     F(i,1,n)scanf("%d",a+i),pos[i]=la[a[i]],la[a[i]]=i;
    48     F(i,1,k)
    49     {
    50         build();
    51         F(j,1,n)update(pos[j],j-1,1),dp[j]=ask(0,j-1);
    52     }
    53     printf("%d
    ",dp[n]);
    54     return 0;
    55 }
    View Code
  • 相关阅读:
    C++实现单例模式
    进程间通信(IPC)介绍
    Python装饰器
    Python中import的使用
    Python中is和==的区别
    SK-Learn使用NMF(非负矩阵分解)和LDA(隐含狄利克雷分布)进行话题抽取
    Focal Loss for Dense Object Detection
    YOLOv3: An Incremental Improvement
    YOLO9000: Better, Faster, Stronger
    You Only Look Once: Unified, Real-Time Object Detection
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7276860.html
Copyright © 2011-2022 走看看