bzoj2298: [HAOI2011]problem a
题目链接
题解
补集转化答案就是n - 最多人说真话
考虑每个人的话构成一段相等成绩区间
令同分数人的个数为区间权值,那么问题就是求最大权不相交区间
代码
/*************************************************************/
#include<map>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
const int maxn = 100007;
int n;
struct node {
int l;int r,size;
node (int l = 0,int r = 0) : l(l) , r(r) {} ;
bool operator < (const node a)const {
if(l != a.l) return l < a.l;
return r < a.r;
}
} ;
std::map <node,int> Seg;
std::vector<int>vec[maxn];
int dp[maxn];
int main() {
n = read();
for(int a,b,i = 1;i <= n;++ i) {
a = read() + 1,b = read();
b = n - b; node Tmp;
if(Seg[Tmp = node(a,b)] < b - a + 1) Seg[Tmp] ++ ;
if(Seg[Tmp] == 1) vec[b].push_back(a);
}
int num = 0;
//std::sort(peo + 1,peo + n + 1);
for(int i = 1;i <= n;++ i) {
dp[i] = dp[i - 1];
for(int j = 0;j < vec[i].size();++ j) {
int l = vec[i][j];
dp[i] = std::max(dp[i],dp[l - 1] + Seg[node(l,i)]);
}
}
printf("%d\n",n - dp[n]);
return 0;
}