BZOJ2298 [HAOI2011]problem a
生活随笔
收集整理的這篇文章主要介紹了
BZOJ2298 [HAOI2011]problem a
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
先把所有人從小到大排序,則
如果一個人說a個人比他大,b個人比他小,等價于他聲稱[b + 1, n - a]的值是相等的
問題轉化為給一些線段,找出一些不重疊的線段,價值最大 (注意:線段可以重合!!!)
然后就是一遍掃過去的DP
f[i]表示以線段i為結尾的滿足條件的線段最多數
f[i] = max(f[j]) + cnt[i], 其中r[j] < l[i], cnt[i]表示i這條線段重合次數
DP要優化的說,不過只要二分一下嘛就好了!
?
1 /************************************************************** 2 Problem: 2298 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:792 ms 7 Memory:5012 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #include <utility> 13 #include <map> 14 15 using namespace std; 16 typedef pair<int, int> P; 17 const int N = 100005; 18 struct data{ 19 int x, y, cnt; 20 bool f; 21 }a[N]; 22 inline bool operator < (const data a, const data b){ 23 return a.y == b.y ? a.x < b.x : a.y < b.y; 24 } 25 map <P, int> M; 26 int n, f[N], X, Y, l; 27 28 inline int read(){ 29 int x = 0, sgn = 1; 30 char ch = getchar(); 31 while (ch < '0' || ch > '9'){ 32 if (ch == '-') sgn = -1; 33 ch = getchar(); 34 } 35 while (ch >= '0' && ch <= '9'){ 36 x = x * 10 + ch - '0'; 37 ch = getchar(); 38 } 39 return sgn * x; 40 } 41 42 int main(){ 43 n = read(); 44 for (int i = 1; i <= n; ++i){ 45 X = read(), Y = read(); 46 a[i].f = (X + Y >= n); 47 a[i].x = n - X, a[i].y = ++Y; 48 if (a[i].x > a[i].y) swap(a[i].x, a[i].y); 49 a[i].cnt = min(M[make_pair(a[i].x, a[i].y)] += a[i].f ^ 1, a[i].y - a[i].x + 1); 50 } 51 sort(a + 1, a + n + 1); 52 for (int i = 1; i <= n; ++i){ 53 if (a[i].f){ 54 f[i] = f[i - 1]; 55 continue; 56 } 57 l = lower_bound(a + 1, a + i, (data){-1, a[i].x}) - a - 1; 58 f[i] = max(f[i - 1], f[l] + a[i].cnt); 59 } 60 printf("%d\n", n - f[n]); 61 return 0; 62 } View Code?
轉載于:https://www.cnblogs.com/rausen/p/4345380.html
總結
以上是生活随笔為你收集整理的BZOJ2298 [HAOI2011]problem a的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSUOJ 1525 Algebraic
- 下一篇: 【转载】Zend Studio 10正式