CF 833 B. The Bakery

Stella981
• 阅读 643

B. The Bakery

http://codeforces.com/contest/833/problem/B

题意:

  将一个长度为n的序列分成k份,每份的cost为不同的数的个数,求最大cost的和。1≤n≤35000,1≤k≤50

分析:

  dp[i][j]表示前i个数,分了j份。dp[i][k]=dp[j][k-1]+cost(j+1,i);cost(j+1,i)为这一段中不同数的个数。

  然后考虑如何优化。发现每次增加一个位置,pre[i]~i-1区间的每个转移的位置的cost+1。然后每次转移是在上一个dp数组中取最大值,于是线段树维护。

代码:

 1 /*
 2 * @Author: mjt
 3 * @Date:   2018-10-15 14:52:11
 4 * @Last Modified by:   mjt
 5 * @Last Modified time: 2018-10-15 15:27:53
 6 */
 7 #include<cstdio>
 8 #include<algorithm>
 9 #include<cstring>
10 #include<cmath>
11 #include<iostream>
12 #include<cctype>
13 #include<set>
14 #include<vector>
15 #include<queue>
16 #include<map>
17 #define fi(s) freopen(s,"r",stdin);
18 #define fo(s) freopen(s,"w",stdout);
19 using namespace std;
20 typedef long long LL;
21 
22 inline int read() {
23     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
24     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
25 }
26 
27 const int N = 35005;
28 
29 int dp[N][55], pre[N], last[N], a[N];
30 int n, k;
31 
32 #define Root 1, n, 1
33 #define lson l, mid, rt << 1
34 #define rson mid + 1, r, rt << 1 | 1
35 struct SegmentTree {
36     int mx[N << 2], tag[N << 2], Cur;
37     inline void pushup(int rt) { mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]); }
38     inline void pushdown(int rt) {
39         if (tag[rt]) {
40             tag[rt << 1] += tag[rt]; mx[rt << 1] += tag[rt];
41             tag[rt << 1 | 1] += tag[rt]; mx[rt << 1 | 1] += tag[rt];
42             tag[rt] = 0;
43         }
44     }
45     void build(int l,int r,int rt) {
46         tag[rt] = 0;
47         if (l == r) {
48             mx[rt] = dp[l][Cur]; return ;
49         }
50         int mid = (l + r) >> 1;
51         build(lson); build(rson);
52         pushup(rt);
53     }
54     void update(int l,int r,int rt,int L,int R) {
55         if (L <= l && r <= R) {
56             mx[rt] ++; tag[rt] ++;
57             return ;
58         }
59         pushdown(rt);
60         int mid = (l + r) >> 1;
61         if (L <= mid) update(lson, L, R);
62         if (R > mid) update(rson, L, R);
63         pushup(rt);
64     }
65     int query(int l,int r,int rt,int L,int R) {
66         if (L <= l && r <= R) {
67             return mx[rt];
68         }
69         pushdown(rt);
70         int mid = (l + r) >> 1, res = 0;
71         if (L <= mid) res = max(res, query(lson, L, R));
72         if (R > mid) res = max(res, query(rson, L, R));
73         return res;
74     }
75 }T;
76 
77 void solve(int now) {
78     T.Cur = now - 1; T.build(Root);
79     for (int i=now; i<=n; ++i) {
80         T.update(Root, pre[i], i - 1); // 线段树维护的是dp[j][now-1]+cost(j+1,i)的值,所以pre[i]~i-1这个区间加1!!!
81         dp[i][now] = T.query(Root, 1, i - 1);
82     }
83 }
84 
85 int main() { 
86     n = read(), k = read();
87     for (int cnt=0,i=1; i<=n; ++i) {
88         a[i] = read();
89         pre[i] = last[a[i]]; last[a[i]] = i;
90         if (pre[i] == 0) cnt ++;
91         dp[i][1] = cnt;
92     }
93     for (int i=2; i<=k; ++i) solve(i);
94     cout << dp[n][k];
95     return 0;
96 }
点赞
收藏
评论区
推荐文章
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Stella981 Stella981
3年前
Codeforces Round #479 (Div. 3) F. Consecutive Subsequence
标签:DP题目链接(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F977%2Fproblem%2FF)
Stella981 Stella981
3年前
Codeforces 1091D New Year and the Permutation Concatenation 找规律,数学 B
Codeforces1091DNewYearandthePermutationConcatenation   https://codeforces.com/contest/1091/problem/D题目:  Letnbeaninteger.Considerallpermutationsonintege
Stella981 Stella981
3年前
Comet OJ
题意https://www.cometoj.com/contest/52/problem/C?problem\_id2416(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cometoj.com%2Fcontest%2F52%2Fproblem%2FC%3Fprob
Stella981 Stella981
3年前
Codeforces Round #611 (Div. 3)
原题面:https://codeforces.com/contest/1283(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fcodeforces.com%2Fcontest%2F1283)A.MinutesBeforetheNewYear题目大意:给定时间,问距离零点
Stella981 Stella981
3年前
Codeforces Round #616 (Div. 2)
A.EvenButNotEven(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F1291%2Fproblem%2FA)题意:给你一个很长的数,可以删减里面的任意数字,要求本身不能除以2,但是该数的各位和能除以2,输出任意符合
Stella981 Stella981
3年前
Codeforces Round #565 (Div. 3) C. Lose it!
链接:https://codeforces.com/contest/1176/problem/C(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fcodeforces.com%2Fcontest%2F1176%2Fproblem%2FC)题意:Youare
Stella981 Stella981
3年前
85D Sum of Medians
传送门(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F85%2Fproblem%2FD)题目Inonewellknownalgorithmoffindingthe_k_\thorderst
Stella981 Stella981
3年前
E. You Are Given Some Strings...
E.YouAreGivenSomeStrings...(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fcodeforces.com%2Fcontest%2F1202%2Fproblem%2FE)AC自动机求一个串$t$中包含子串$s\_{i}s\_{j}$的个数。
Stella981 Stella981
3年前
Codeforces 1244G. Running in Pairs
传送门(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fcodeforces.com%2Fcontest%2F1244%2Fproblem%2FG)首先对于两个排列$A,B$我们可以把$A$从小到大排序并把$B$重新和$A$一一对应显然这样不会影响$\\sum\