1. 程式人生 > >Codeforces Gym 101623A

Codeforces Gym 101623A

題目傳送門

  傳送門

題目大意

  給定一個長度為$n$的序列,要求劃分成最少的段數,然後將這些段排序使得新序列單調不減。

  考慮將相鄰的相等的數縮成一個數。

  假設沒有分成了$n$段,考慮最少能夠減少多少劃分。

  我們將這個序列排序,對於權值相同的一段數可以任意交換它們,每兩個相鄰數在原序列的位置中如果是$i, i + 1$,那麼劃分的段數就可以減少1.

  每次轉移我們考慮新增值相同的一段。

  每次轉移能不能將減少的段數加一取決於當前考慮的數在前一段內有沒有出現以及有沒有作為最左端點。

  因此我們記錄一個決策與最優解不同的次優解就能轉移了。

Code

  1
/** 2 * Codeforces 3 * Gym#101623A 4 * Accepted 5 * Time: 171ms 6 * Memory: 18300k 7 */ 8 #include <algorithm> 9 #include <iostream> 10 #include <cassert> 11 #include <cstdlib> 12 #include <cstdio> 13 using namespace std; 14 typedef bool
boolean; 15 16 #define pii pair<int, int> 17 #define fi first 18 #define sc second 19 20 ostream& operator << (ostream& out, pii x) { 21 out << "(" << x.fi << ", " << x.sc << ")"; 22 return out; 23 } 24 25 template <typename T> 26
void pfill(T* pst, const T* ped, T val) { 27 for ( ; pst != ped; *(pst++) = val); 28 } 29 30 template <typename T> 31 void pcopy(T* pst, const T* ped, T *pval) { 32 for ( ; pst != ped; *(pst++) = *(pval++)); 33 } 34 35 int n; 36 int *ar; 37 pii *ps; 38 39 inline void init() { 40 scanf("%d", &n); 41 ar = new int[(n + 1)]; 42 for (int i = 1; i <= n; i++) 43 scanf("%d", ar + i); 44 } 45 46 int *ss, *st; 47 boolean *exi; 48 inline void solve() { 49 ps = new pii[(n + 1)]; 50 ss = new int[(n + 1)]; 51 st = new int[(n + 1)]; 52 exi = new boolean[(n + 1)]; 53 pfill(exi, exi + n + 1, false); 54 int m = 0, diff = 0; 55 for (int i = 1; i <= n; i++) 56 if (i == 1 || ar[i] != ar[i - 1]) 57 ps[++m] = pii(ar[i], ++diff); 58 sort(ps + 1, ps + (n = m) + 1); 59 // for (int i = 1; i <= m; i++) 60 // cerr << ps[i] << endl; 61 ss[1] = 1; 62 for (int i = 2; i <= n; i++) 63 ss[i] = ((ps[i - 1].first == ps[i].first) ? (ss[i - 1]) : (i)); 64 st[n] = n; 65 for (int i = n - 1; i; i--) 66 st[i] = ((ps[i + 1].first == ps[i].first) ? (st[i + 1]) : (i)); 67 68 ss[0] = st[0] = 0; 69 pii f(0, -1), g(-14285700, -1), cf(-1, -1), cg(-1, -1); 70 for (int i = 1; i <= n; i++) { 71 if (ss[i] != i) 72 continue; 73 for (int j = max(ss[i - 1], 1); j <= st[i - 1]; j++) 74 exi[ps[j].second] = true; 75 for (int j = ss[i], x, uval; j <= st[i]; j++) { 76 x = ps[j].second; 77 if (exi[x - 1]) { 78 if (x - 1 == f.second && st[i - 1] > ss[i - 1]) 79 assert(x - 1 != g.second), uval = g.first + 1; 80 else 81 uval = f.first + 1; 82 uval = max(uval, f.first); 83 } else 84 uval = f.first; 85 if (uval > cf.first) 86 cg = cf, cf = pii(uval, x); 87 else if (x != cg.second && uval > cg.first) 88 cg = pii(uval, x); 89 } 90 for (int j = max(ss[i - 1], 1); j <= st[i - 1]; j++) 91 exi[ps[j].second] = false; 92 swap(cf, f); 93 swap(cg, g); 94 cf = pii(-14285700, -1), cg = pii(-14285700, -1); 95 // cerr << f << " " << g << endl; 96 } 97 printf("%d\n", n - f.first - 1); 98 } 99 100 int main() { 101 init(); 102 solve(); 103 return 0; 104 }

相關推薦

Codeforces Gym 101623A - 動態規劃

個數 最優解 print ref val 我們 oid end pair 題目傳送門   傳送門 題目大意   給定一個長度為$n$的序列,要求劃分成最少的段數,然後將這些段排序使得新序列單調不減。   考慮將相鄰的相等的數縮成一個數。   假設沒有分

Codeforces Gym 101623A

題目傳送門   傳送門 題目大意   給定一個長度為$n$的序列,要求劃分成最少的段數,然後將這些段排序使得新序列單調不減。   考慮將相鄰的相等的數縮成一個數。   假設沒有分成了$n$段,考慮最少能夠減少多少劃分。   我們將這個序列排序,對於權值相同的一段數可以任意交換它們,每兩

codeforces gym 101164 K Cutting 字符串hash

暴力 print pre clas 暴力枚舉 cut ash pac lin 題意:給你兩個字符串a,b,不區分大小寫,將b分成三段,重新拼接,問是否能得到A; 思路:暴力枚舉兩個斷點,然後check的時候需要字符串hash,O(1)復雜度N*N; 題目鏈接:傳送門

Codeforces Gym 100269 Dwarf Tower (最短路)

pair iostream printf sync part ret scribe first pan 題目連接: http://codeforces.com/gym/100269/attachments Description Little Vasya is playin

codeforces Gym 101063 C

blank ostream con ans pac sin %d sca mes 二進制轉十進制 然後按位比較 傳送門 http://codeforces.com/gym/101063 #include <cstdio> #include <cma

Codeforces Gym 101194G Pandaria (2016 ACM-ICPC EC-Final G題, 並查集 + 線段樹合並)

body end highlight 題目 efi 預處理 ++i sin const 題目鏈接 2016 ACM-ICPC EC-Final Problem G 題意 給定一個無向圖。每個點有一種顏色。    現在給定$q$個詢問,每次詢問$x$和$w$,求所有能

codeforces gym 100548f

打表 需要 turn name pri 不同 也有 info include 題目如圖 題意是說給n個花,m種顏色,要求相鄰花顏色不能相同,總共有k種不同的顏色。   剛開始想的是從m種顏色裏選k種,然後第一朵花有k種選法,後面的都是k-1種,這樣就是C(m,k) * (

Codeforces Gym 101190 NEERC 16 .D Delight for a Cat (上下界的費用流)

至少 light bool clu back 技術分享 || 方案 思路 ls是一個特別墮落的小朋友,對於n個連續的小時,他將要麽睡覺要麽打隔膜,一個小時內他不能既睡覺也打隔膜 ,因此一個小時內他只能選擇睡覺或者打隔膜,當然他也必須選擇睡覺或打隔膜,對於每一個小時,他選擇

CodeForces gym Nasta Rabbara lct

cond n) signed lin aps 等於 scan turn pair Nasta Rabbara 題意:簡單來說就是, 現在有 n個點, m條邊, 每次詢問一個區間[ l , r ], 將這個區間的所有邊都連上, 如果現在的圖中有奇數環, 就輸出 “Impos

Codeforces Gym 101174 B Within Arm's Reach 極角排序

line his push include with sort begin codeforce bsp #include<stdio.h> #include <vector> #include <algorithm> using nam

Codeforces Gym 101174 A Within Arm's Reach 貪心 手臂

oid bsp stream def else return mat hang std #include<iostream> #include<stdio.h> #include <string.h> #include <algo

Codeforces Gym 101174 J Risky Lottery 計算方法 逼近求值 dfs

ref rem sin else 情況下 fab cnblogs clu fine #include<stdio.h> #include <math.h> using namespace std; int fac[10],a[10]; #defi

CodeForces Gym 100228 Graph of Inversions

!= 定義 stream i++ pac 不難 string fin style 題目大意 對於一個長為$N$的序列$A$,定義它所對應的逆序圖: 有$N$個點組成,標號為$1...N$的無向圖,對於每一組$i,j(i<j)$若存在$A_i>A_j$則在新圖

Codeforces GYM 101968 A. Tree Game

差點自閉,感謝大佬幫忙找bug 題目:https://codeforces.com/gym/101968/problem/A 找樹的重心+思維 找到樹的重心,如果重心只有一個,以重心為根節點dfs,求各節點深度,那麼任意一對節點都符合題意,只要讓先手mark深度小的節點即可,其中同樣深度的節點,交換位置

Codeforces Gym 100548H - The Problem to Make You Happy 2014 ACM-ICPC 西安站

Problem H. The Problem to Make You Happy Input file: standard input Output file: standard output Time limit: 1 seconds Memory lim

Codeforces Gym 101933 K King's Colors

題目分析 題目要求在樹上塗上恰好\(K\)種顏色的方案數。 設\(f(k)\)表示恰好塗上\(k\)種顏色的方案數(答案即為\(f(K)\))。 設\(g(k)\)表示至多塗上\(k\)種顏色的方案數。 顯然有:\(g(k)=\sum\limits_{i=1}^k\dbinom{k}{i}f(i)\)

codeforces gym】Increasing Costs

有一個 friend push_back line push pri ems tor [1] Portal --> Increasing Costs Description   給你一個\(n\)個點無重邊無自環的無向連通圖,每條邊有一個邊權,對於每一條邊,詢問去掉這

codeforces Gym

                                      Problem A. Archery Tournament Time limit: 3 seconds You were invited to the annual archery tournam

codeforces gym 101889J – Jumping Frog ( 數學+ 思維 好題 )

思路 :青蛙每次跳長度為len  的距離,如果想要回到原點,那麼青蛙跳的點數一定是固定的,把跳過的點標記成紅色,那麼相鄰的兩個紅點之間的距離也一定是字串長度n 的因子。那麼就問題就可以轉化成每次跳長度為兩個紅點的距離,能否滿足題意。那麼我就可以直接暴力處理長度n 的所有因

[Codeforces-Gym] (101667C) ---- DFS+記憶化剪枝★

題目傳送門 題意: 給你一個無權無向圖,n個頂點,m個城市。讓你找一最長的序列[s1,s2,s3,……sk] 滿足頂點si+1的度> si的度,並且si與si+1相鄰。 做法: 搜尋每個點,