P2519 [HAOI2011]problem a

想不到啊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

原文地址:https://www.cnblogs.com/Jackpei/p/11590294.html