BZOJ2298 [HAOI2011]problem a

2298: [HAOI2011]problem a

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1505  Solved: 743
[Submit][Status][Discuss]

Description

一次考试共有n个人参加,第i个人说:“有ai个人分数比我高,bi个人分数比我低。”问最少有几个人没有说真话(可能有相同的分数)

 

Input

第一行一个整数n,接下来n行每行两个整数,第i+1行的两个整数分别代表ai、bi

Output

一个整数,表示最少有几个人说谎

 

Sample Input

3

2 0

0 2

2 2



Sample Output


1

HINT


100%的数据满足: 1≤n≤100000   0≤ai、bi≤n

题解:按照这个人所说的可以知道这个人排名的区间,这样就可以统计一段一段这样的区间,

每段有多少人就知道了,然后就是dp,f[i]表示前i个说真话的最多有几个人,然后进行转移

该区间,从前面那些区间开始,然后转移就是l-r这个区间和f[l-1]这里,就ok了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<vector>
 7 #include<map>
 8 #define N 100007
 9 #define fzy pair<int,int>
10 using namespace std;
11 
12 int n;
13 int f[N];
14 vector<int>q[N];
15 map<fzy,int>p;
16 
17 int main()
18 {
19     scanf("%d",&n);
20     int x,y;
21     for (int i=1;i<=n;i++)
22     {
23         scanf("%d%d",&x,&y);
24         int l=x+1,r=n-y;
25         if (l>r) continue;
26         p[make_pair(l,r)]++;
27         if (p[make_pair(l,r)]==1) q[r].push_back(l);
28     }
29     for (int i=1;i<=n;i++)
30     {
31         f[i]=f[i-1];
32         for (int j=0;j<q[i].size();j++)
33             f[i]=max(f[i],f[q[i][j]-1]+min(i-q[i][j]+1,p[make_pair(q[i][j],i)]));
34     }
35     printf("%d\n",n-f[n]);
36 }

 



 

posted @ 2017-10-12 15:14  Kaiser-  阅读(125)  评论(0编辑  收藏  举报