[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 }

 

转载于:https://www.cnblogs.com/Comfortable/p/9832663.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值