Luogu_P2519 [HAOI2011]problem a【题解】DP
作者:互联网
题面:https://www.luogu.org/problem/P2519
题面真简单。
设这个人的名次为他前面的人数加1。
那么我们可以知道n-bi-ai就是并列的人数。
设l为ai+1设r为n-bi。
那么并列人数就是r-l+1。
那么自然就是求若干的不相交的段,使他们的价值和最大。
设fi为到i的最大的价值和。
f[i]=max(f[i-1],f[now]+v[i]);
代码如下:
#include<bits/stdc++.h> using namespace std; const int maxn=100010; struct node{ int l,r,v; }a[maxn],b[maxn]; int cnt,n,tot,f[maxn]; inline bool cmp1(node x,node y){return x.l==y.l ? x.r<y.r : x.l<y.l ;} inline bool cmp2(node x,node y){return x.r==y.r ? x.l<y.l : x.r<y.r ;} inline int erf(int l,int r,int d){ while(l<=r){ int mid=(l+r)>>1; if(a[mid].r<d) l=mid+1; else r=mid-1; } return r; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++){ int x,y;scanf("%d%d",&x,&y); a[i].l=x+1;a[i].r=n-y; } sort(a+1,a+1+n,cmp1); for(int i=1;i<=n;i++) if(a[i].l<=a[i].r) b[++tot]=a[i]; for(int i=1;i<=tot;i++) if(i==1 || b[i].l !=b[i-1].l || b[i].r!=b[i-1].r) a[++cnt]=b[i],a[cnt].v=1; else if(a[cnt].v<a[cnt].r-a[cnt].l+1) a[cnt].v++; sort(a+1,a+1+cnt,cmp2); f[1]=a[1].v; for(int i=2;i<=cnt;i++){ int now=erf(1,i-1,a[i].l); f[i]=max(f[i-1],f[now]+a[i].v); } printf("%d\n",n-f[cnt]); return 0; }
标签:node,P2519,int,题解,ai,maxn,Luogu,题面 来源: https://www.cnblogs.com/ChrisKKK/p/11589023.html