Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // DP - Divide and Conqueor Optimization
- #include <bits/stdc++.h>
- using namespace std;
- #define MAX 350005
- int col[MAX];
- int cnt[MAX], wh[MAX], tim = 0;
- int after[MAX], pos[MAX];
- int dp[MAX][55], n, k;
- int ans = 0;
- void calc(int part, int l, int r, int optl, int optr)
- {
- if(l > r) return;
- int mid = (l+r)/2;
- int best = 0, opt = -1;
- ans = 0;
- // clr();
- //++tim, ans = 0;
- //range(min(mid-1, optr)+1, mid);
- for(int i=min(mid-1, optr)+1; i<=mid; i++){
- //if(wh[col[i]] != tim) wh[col[i]] = tim, cnt[col[i]] = 0;
- //if(cnt[col[i]] == 0) ans++;
- //cnt[col[i]]++;
- if(after[i] > mid) ans++;
- }
- for(int i=min(mid-1, optr); i>=optl; i--){
- int cur = dp[i][part-1] + ans;
- if(cur > best) best = cur, opt = i;
- //range(i, i);
- //if(wh[col[i]] != tim) wh[col[i]] = tim, cnt[col[i]] = 0;
- //if(cnt[col[i]] == 0) ans++;
- //cnt[col[i]]++;
- if(after[i] > mid) ans++;
- }
- if(opt == -1) return;
- dp[mid][part] = best;
- calc(part, l, mid-1, optl, opt);
- calc(part, mid+1, r, opt, optr);
- }
- int main()
- {
- scanf("%d %d", &n, &k), k--;
- for(int i=1; i<=n; i++) scanf("%d", &col[i]);
- for(int i=1; i<=n; i++) pos[i] = n+1;
- for(int i=n; i>=1; i--){
- after[i] = pos[col[i]];
- pos[col[i]] = i;
- }
- ++tim, ans = 0;
- for(int i=1; i<=n; i++){
- if(wh[col[i]] != tim) wh[col[i]] = tim, cnt[col[i]] = 0;
- if(cnt[col[i]] == 0) ans++;
- cnt[col[i]]++;
- dp[i][0] = ans;
- }
- for(int i=1; i<=k; i++) calc(i, 0, n, 0, n);
- int ans = dp[n][k];
- cout << ans;
- }
Advertisement
Add Comment
Please, Sign In to add comment