[dp][贪心] Jzoj P2519 problem a

题目描述

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:
3
2 0
0 2
2 2
输出样例#1:
1

说明

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

题解

  • 答案可以转换为n-最多将真话的人
  • 设f[i]为前i个人中说真话的人的最多人数,转移显然
  • 假设现在做到第j个,要使i~j中的人的分数都相等(因为如果还有更小的话早就处理了)
  • 那f[i]=f[j-1]+sum[j][i](j<=i),求这个sum数组可以用map来做

代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <map>
 4 #include <vector>
 5 using namespace std;
 6 int n,f[100010];
 7 vector<int>l[100010];
 8 map<pair<int,int>,int>s;
 9 int main()
10 {
11     scanf("%d",&n);
12     for (int i=1,x,y;i<=n;i++)
13     {
14         scanf("%d%d",&x,&y);
15         x++,y=n-y;
16         if (x>y) continue;
17         if (++s[make_pair(x,y)]==1) l[y].push_back(x);
18     }
19     for (int i=1;i<=n;i++)
20     {
21         f[i]=f[i-1];
22         for (int j=0;j<l[i].size();j++) f[i]=max(f[i],f[l[i][j]-1]+min(i-l[i][j]+1,s[make_pair(l[i][j],i)]));
23     }
24     printf("%d",n-f[n]);
25 }

猜你喜欢

转载自www.cnblogs.com/Comfortable/p/9832663.html
今日推荐