AFO

[JLOI2013]地形生成

3193

首先按照第一关键字高度倒叙,第二关键字顺序的顺序排序

第一问O(n) dp一下

考虑一下第i个山能放在哪些山的后面,对于比第i个山高的,只能放在前关键字个的后面,但排在他的前面的和他一样高的的后面都可以放,因为他的关键字比已放的大

第二问大概就不能O(n)了...

我们强制让一样高的关键字从小到大排列。如果\(d[i]\)表示当前一个放在第 i个比他们高的后面,可以从\(i\in[0,i-1]\)转移过来


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;
const int P = 2011;
const int M = 1101;
int res=1,n,m,k,sum,f[M],d[M];

struct vv
{
	int x,y;
}a[M];
bool cmp(vv a,vv b) { return a.x!=b.x ? a.x>b.x: a.y<b.y; } 

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++)
	{
		if(a[i].x!=a[i-1].x) 
		{
			sum+=k;
			k=0;
		}
		res=res*(min(a[i].y,sum+1)+k)%P;
		k++;
	}
	printf("%d ",res);
	sum=0; res=1;
	for(int i=1;i<=n;)
	{
		int z=i;
		while(a[i].x==a[z].x) z++;
		memset(d,0,sizeof(d));
		d[0]=1;
		for(int j=i;j<z;j++)
		{
			f[0]=1;
			for(int l=1;l<=sum;l++) f[l]=(f[l-1]+d[l])%P;
			for(int l=1;l<a[j].y;l++) d[l]=(d[l]+f[l-1])%P;
		}
		int k=0;
		for(int j=0;j<=sum;j++) k+=d[j];
		k%=P; sum+=z-i; i=z;
		res=res*k%P;
	}
	printf("%d",res);
}
posted @ 2019-06-27 09:25  ZUTTER☮  阅读(205)  评论(0编辑  收藏  举报