想不到啊QwQ
思路:转化+DP
提交:1次
题解:
首先若比他分数高的+分数低的>n-1显然是假的;把相同分的人看作一个区间:左端点为 分数更低的人数,右端点为 n - 分数更高的人数。同时我们统计有多少个相同的区间(多少个人说过的这句话),作为这个区间的权值。然后现在我们就是要最大化不交区间的权值(人数)。所以转化完了直接DP;
#include<bits/stdc++.h>
#define R register int
using namespace std;
namespace Luitaryi {
inline int g() { R x=0,f=1;
register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
} const int N=100010;
int n,m,cnt,f[N];
struct node { int l,r,w;
inline bool operator < (const node& that) const
{return l<that.l||l==that.l&&r<that.r;}
inline bool operator > (const node& that) const
{return r<that.r||r==that.r&&l<that.l;}
}a[N];
inline void main() {
m=n=g(); for(R i=1;i<=n;++i) {
a[++cnt].l=g(),a[cnt].r=n-g();
if(a[cnt].l>=a[cnt].r) --cnt;
} n=cnt,cnt=0; sort(a+1,a+n+1),a[0].l=-1;
for(R i=1;i<=n;++i) if(a[i].l!=a[i-1].l||a[i].r!=a[i-1].r) {
a[++cnt]=a[i],a[cnt].w=1;
} else if(a[cnt].w!=a[i].r-a[i].l) ++a[cnt].w; n=cnt;
sort(a+1,a+n+1,greater<node>()); R p=1;
for(R i=1;i<=m;++i) { f[i]=f[i-1];
while(p<=n&&a[p].r==i) f[i]=max(f[i],f[a[p].l]+a[p].w),++p;
} printf("%d
",m-f[m]);
}
} signed main() {Luitaryi::main(); return 0;}
2019.09.26
50