6654. 【2020.05.27省选模拟】数据结构

时间:2020-05-29
本文章向大家介绍6654. 【2020.05.27省选模拟】数据结构,主要包括6654. 【2020.05.27省选模拟】数据结构使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目描述


题解

dyptql

考虑把区间拆成左右端点排序,左端点可以和至多一个右端点匹配

显然如果一个左端点不和之前的右端点匹配,那么这些右端点必须要在之后匹配

设f[i][j][k]表示做到第i个点,有j个右端点可以匹配,k个必须匹配的方案

随便转移

code

#include <bits/stdc++.h>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define add(a,b) a=((a)+(b))%1000000007
#define mod 1000000007
#define ll long long
#define file
using namespace std;

struct type{
	int x,s;
} a[1001];
ll f[2][501][501],ans;
int tot,n,i,j,k,l,I,I2;

bool cmp(type a,type b) {return a.x<b.x || a.x==b.x && a.s<b.s;}

int main()
{
	freopen("ds.in","r",stdin);
	#ifdef file
	freopen("ds.out","w",stdout);
	#endif
	
	scanf("%d",&n);
	fo(i,1,n) scanf("%d%d",&j,&k),a[++tot]={j,1},a[++tot]={k,0};
	
	sort(a+1,a+tot+1,cmp);
	f[0][0][0]=1;I=0;
	fo(i,0,tot-1)
	{
		I2=I^1;memset(f[I2],0,sizeof(f[I2]));
		fo(j,0,n)
		{
			fo(k,0,n-j)
			if (f[I][j][k])
			{
				if (!a[i+1].s)
				{
					add(f[I2][0][j+k],f[I][j][k]);
					if (j) add(f[I2][j-1][k],f[I][j][k]*j);
					if (k) add(f[I2][j][k-1],f[I][j][k]*k);
				}
				else
				add(f[I2][j+1][k],f[I][j][k]);
			}
		}
		I=I2;
	}
	
	fo(i,1,n) add(ans,f[I][i][0]);
	printf("%lld\n",ans);
	
	fclose(stdin);
	fclose(stdout);
	return 0;
}

原文地址:https://www.cnblogs.com/gmh77/p/12989651.html