【BZOJ1229】【USACO2008 Nov】toy 玩具
【BZOJ3781】小B的询问

【BZOJ2298】【HAOI2011】problem a

Zarxdy34 posted @ 2016年3月03日 18:09 in BZOJ with tags DP , 412 阅读

  很显然一个DP,一个人有\(a_i\)个人分数比他高,\(b_i\)个人分数比他低,那么这个人对应的名次区间就是\([b_i + 1 , n - a_i]\),最多的说真话的人数就是能选出最多的不相交的(或者相等的)名次区间。一个名次区间\([a , b]\)最多有\(b-a+1\)个人说真话。

 

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=100010;

struct Edge {int u,v;}E[maxn];
bool cmp(const Edge &a,const Edge &b) {return a.u<b.u || a.u==b.u && a.v<b.v;}

int f[maxn];
int n,Ecnt;

int main()
{
	scanf("%d",&n);
	for (int i=1,x,y;i<=n;i++) 
	{
		scanf("%d%d",&x,&y);
		if (x+y>=n) continue;
		Ecnt++;
		E[Ecnt].u=n-x;
		E[Ecnt].v=y;
	}
	sort(E+1,E+1+Ecnt,cmp);
	for (int i=1,j=1;i<=n;i++)
	{
		while (j<=Ecnt && E[j].u==i)
		{
			int cnt=1;
			while (j<Ecnt && E[j+1].u==i && E[j+1].v==E[j].v) cnt++,j++;
			f[i]=max(f[i],f[E[j].v]+min(cnt,E[j].u-E[j].v));
			j++;
		}
		f[i]=max(f[i],f[i-1]);
	}
	printf("%d\n",n-f[n]);
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter