【BZOJ 2298】 2298: [HAOI2011]problem a (DP)

2298: [HAOI2011]problem a

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1326  Solved: 637

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





Source

 

 

 

【分析】

  啊。。主要是这么搞笑的题目我错了2次。。。【还要对拍。。。

  题目可以弄成n个区间,意思是这n个区间的分数要一样的。

  显然区间不能相交但是可以完全重合。

  把完全重合的区间合并起来,就是一个带权的最大不相交区间了。

  这个直接DP。。

  还有一个我后来错了就是那个区间的权值不能大于那个区间的规模,要取一下min。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 100010
 8 
 9 int mymax(int x,int y) {return x>y?x:y;}
10 int mymin(int x,int y) {return x<y?x:y;}
11 
12 struct node
13 {
14     int x,y,c;
15 }t[Maxn];
16 
17 bool cmp(node x,node y) {return x.y==y.y?(x.x>y.x):(x.y<y.y);}
18 
19 int f[Maxn];
20 
21 int main()
22 {
23     int n;
24     scanf("%d",&n);
25     int cnt=0;
26     for(int i=1;i<=n;i++)
27     {
28         int x,y;
29         scanf("%d%d",&x,&y);
30         if(x+y>=n) continue;
31         t[++cnt].x=x+1;t[cnt].y=n-y;t[cnt].c=1;
32     }
33     sort(t+1,t+1+cnt,cmp);
34     int p=1;
35     for(int i=2;i<=cnt;i++)
36     {
37         if(t[i].x==t[p].x&&t[i].y==t[p].y) t[p].c++;
38         else t[++p]=t[i];
39     }
40     for(int i=1;i<=p;i++) t[i].c=mymin(t[i].c,t[i].y-t[i].x+1);
41     memset(f,0,sizeof(f));
42     f[0]=0;t[0].y=0;
43     for(int i=1;i<=p;i++)
44     {
45         if(t[i].y!=t[i-1].y||i==1)
46         {
47             for(int j=t[i-1].y+1;j<=t[i].y;j++) f[j]=mymax(f[j],f[j-1]);
48         }
49         f[t[i].y]=mymax(f[t[i].y],f[t[i].x-1]+t[i].c);
50     }
51     printf("%d\n",n-f[t[p].y]);
52     return 0;
53 }
View Code

 

2017-04-05 09:55:53

posted @ 2017-04-05 09:55  konjak魔芋  阅读(255)  评论(0编辑  收藏  举报