题意:n个人,每个人都说剩下人中比自己分数高的人有ai个,比自己分数低的有bi个,问最少有多少人说谎。题中允许同分人出现。
题解:我们可以这么考虑,在所有人中,当前人的排名是[ai+1,n-bi]。在一个合法的情况下,任意两个人的区间是不能相交的。对于一对(i,j),可能会出现ai=aj,bi=bj.所以每个区间相当于有一个权值,代表这个选择这个区间的能带来多少人没有说谎。最后题目就转化成1-n的区间内,选择一些不相交区间使得区间权值和最大。(注意考虑区间的权值不能大于区间长度)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,l,r,tot;
map<pair<int,int>, int >mp;
struct node{
int l,r;
bool operator<(const node a)const{
if (r!=a.r)return r<a.r;
else return l<a.l;
}
}p[maxn];
int dp[maxn];
int main() {
scanf("%d",&n);
for (int i=1;i<=n;i++){
scanf("%d%d",&l,&r);
if (l+r>=n)continue;
int a=l+1,b=n-r;
mp[make_pair(a,b)]++;
if (mp[make_pair(a,b)]==1)p[++tot]={a,b};
}
sort(p+1,p+tot+1);
int nowp=1;
for (int i=1;i<=n;i++){
dp[i]=dp[i-1];
while (nowp<=tot&&i>=p[nowp].r){
dp[i]=max(dp[i],dp[p[nowp].l-1]+min(p[nowp].r-p[nowp].l+1,mp[make_pair(p[nowp].l,p[nowp].r)]));
nowp++;
}
}
cout<<n-dp[n]<<endl;
return 0;
}



京公网安备 11010502036488号