BZOJ2298 [HAOI2011]problem a
2298: [HAOI2011]problem a
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 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
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 }