zoukankan      html  css  js  c++  java
  • CodeForces 834D The Bakery

    The Bakery

    题意:将N个数分成K块, 每块的价值为不同数字的个数, 现在求总价值最大。

    题解:dp[i][j] 表示 长度为j 且分成 i 块的价值总和。 那么 dp[i][j] = max(dp[i-1][x]+右边的数的贡献) ( 1<=x < j )。 如果每次都从左到右for过去一定会TLE, 所以我们用线段树来优化这个查询的过程, 并且用滚动数组消去第二维空间。

    每次新扫到一个数T, 他就会在上一个T的位置+1 --- 现在这个T的位置产生数目加一的贡献。

    然后每次扫完一次, 都用DP的值去重新建树。并且将DP的对应位置往右移动一位, 这样下次访问这个位置就是  dp[i-1][x-1] + dp[1][x-j]的价值了。 (j 为现在的位置)。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define LL long long
     4 #define ULL unsigned LL
     5 #define fi first
     6 #define se second
     7 #define lson l,m,rt<<1
     8 #define rson m+1,r,rt<<1|1
     9 #define max3(a,b,c) max(a,max(b,c))
    10 const int INF = 0x3f3f3f3f;
    11 const LL mod = 1e9+7;
    12 typedef pair<int,int> pll;
    13 const int N = 35010;
    14 int dp[N], tree[N<<2], lazy[N<<2], pos[N], last[N];
    15 void Push_Up(int rt){
    16     tree[rt] = max(tree[rt<<1], tree[rt<<1|1]);
    17 }
    18 void Push_Down(int rt){
    19     if(lazy[rt]){
    20         lazy[rt<<1]+=lazy[rt];
    21         lazy[rt<<1|1]+=lazy[rt];
    22         tree[rt<<1]+=lazy[rt];
    23         tree[rt<<1|1]+=lazy[rt];
    24         lazy[rt] = 0;
    25     }
    26 }
    27 void Build(int l, int r, int rt){
    28     lazy[rt] = 0;
    29     if(l == r){
    30         tree[rt] = dp[l-1];
    31         return ;
    32     }
    33     int m = l+r >> 1;
    34     Build(lson);
    35     Build(rson);
    36     Push_Up(rt);
    37 }
    38 void Update(int L, int R, int l, int r, int rt){
    39     if(L <= l && r <= R){
    40         lazy[rt]++;
    41         tree[rt]++;
    42         return;
    43     }
    44     int m = l+r >> 1;
    45     Push_Down(rt);
    46     if(L <= m) Update(L,R,lson);
    47     if(m < R) Update(L,R,rson);
    48     Push_Up(rt);
    49 }
    50 int Query(int L, int R, int l, int r, int rt){
    51     if(L <= l && r <= R) return tree[rt];
    52     int ans = 0;
    53     int m = l+r >> 1;
    54     Push_Down(rt);
    55     if(L <= m) ans = max(ans, Query(L,R,lson));
    56     if(m < R) ans = max(ans, Query(L,R,rson));
    57     return ans;
    58 }
    59 int main(){
    60     memset(pos, 0, sizeof(pos));
    61     memset(last, 0, sizeof(last));
    62     int n, k, t;
    63     scanf("%d%d",&n,&k);
    64     for(int i = 1; i <= n; i++){
    65         scanf("%d",&t);
    66         last[i] = pos[t] + 1;
    67         pos[t] = i;
    68     }
    69     for(int i = 1; i <= k; i++){
    70         Build(1,n,1);
    71         for(int j = 1; j <= n; j++){
    72             Update(last[j],j,1,n,1);
    73             dp[j] = Query(1,j,1,n,1);
    74         }
    75     }
    76     printf("%d
    ", dp[n]);
    77     return 0;
    78 }
    View Code
  • 相关阅读:
    JS兼容性总结
    [妙味DOM]第五课:事件深入应用
    关于iOS开发的学习
    世界经典——乔布斯
    梦想改变世界
    乔布斯在斯坦福大学的演讲
    10步让你成为更优秀的程序员
    程序员的八个级别
    程序员的学习和积累
    哈佛大学二十条训言
  • 原文地址:https://www.cnblogs.com/MingSD/p/8502843.html
Copyright © 2011-2022 走看看