【JZOJ6654】【2020.05.27省选模拟】数据结构
一道隐藏很深的水题。。。。。
题目大意
题解
很重要的性质是\(B_i<A_i\),这保证了\(i\)不能套在\(i\)里面。于是我们把所有的\(A_i,B_i\)放在一起排序,一个\(B\)点可以和前面任意一个\(A\)点匹配,我们要求最大匹配的方案数。
考虑遇到一个\(B_i\)的时候,如果选择和前面某个未匹配的\(A_j\)匹配,则没有影响,如果选择让它不和前面任何一个未匹配的\(A_j\)匹配,那么前面所有的未匹配的\(A_j\)都必须要在后面找到匹配的\(B_k\),否则就始终有一个匹配\(A_j\ -\ B_i\)未选,使得结果并不是最大匹配了。我们记录一个三维状态\(f_{i,j,k}\),\(i\)表示前\(i\)个点,\(j\)表示未匹配的\(A\)点个数,\(k\)表示由于前面放空某个\(B\)点而导致必须匹配的\(A\)点个数(是包括在\(j\)个未匹配\(A\)点里的)。
转移很简单,遇到\(A\)点时直接\(j=j+1\),遇到\(B\)点时考虑三种情况:
- 放空这个\(B\)点,\(f[i+1][j][j]\leftarrow f[i][j][k]\)。
- 将这个\(B\)点与前面某个必须匹配的\(A\)点匹配,\(f[i+1][j-1][k-1]\leftarrow f[i][j][k]*k\)。
- 将这个\(B\)点与前面某个非必须匹配的\(A\)点匹配,\(f[i+1][j-1][k]\leftarrow f[i][j][k]*(j-k)\)。
最后\(ans=\sum_{j=0}^{N}f[tot][j][0]\),即不存在必须匹配的\(A\)点的所有状态。
滚动一下数组节省空间。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=307;
const ll P=1e9+7;
int n,len,l[N],r[N];
ll ans,f[2][N][N];
struct note{int pos,typ;}p[N<<1];
int cmp(note a,note b){return a.pos==b.pos?a.typ<b.typ:a.pos<b.pos;}
int main(){
freopen("ds.in","r",stdin);
//freopen("ds.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d%d",&r[i],&l[i]),p[++len]=(note){l[i],0},p[++len]=(note){r[i],1};
sort(p+1,p+len+1,cmp);
f[0][0][0]=1;
for(int i=0,a=0,b;i<len;++i,a^=1){
b=a^1;memset(f[b],0,sizeof(f[b]));
if(p[i+1].typ){
for(int j=0;j<=n;++j)for(int k=0;k<=j;++k)if(f[a][j][k]>0)f[b][j+1][k]=(f[b][j+1][k]+f[a][j][k])%P;
}else{
for(int j=0;j<=n;++j)for(int k=0;k<=j;++k)if(f[a][j][k]>0){
if(j>0){
f[b][j-1][k]=(f[b][j-1][k]+f[a][j][k]*(j-k))%P;
if(k>0)f[b][j-1][k-1]=(f[b][j-1][k-1]+f[a][j][k]*k)%P;
}
f[b][j][j]=(f[b][j][j]+f[a][j][k])%P;
}
}
}
ans=0;
for(int j=0;j<=n;++j)ans=(ans+f[len&1][j][0])%P;
printf("%lld\n",ans);
return 0;
}
作者:zjlcnblogs
出处:https://www.cnblogs.com/zjlcnblogs/p/12989680.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】博客园的心动:当一群程序员决定开源共建一个真诚相亲平台
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】Flutter适配HarmonyOS 5知识地图,实战解析+高频避坑指南
【推荐】开源 Linux 服务器运维管理面板 1Panel V2 版本正式发布
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· MySQL索引完全指南:让你的查询速度飞起来
· 一个字符串替换引发的性能血案:正则回溯与救赎之路
· 为什么说方法的参数最好不要超过4个?
· C#.Net 筑基-优雅 LINQ 的查询艺术
· 一个自认为理想主义者的程序员,写了5年公众号、博客的初衷
· MySQL索引完全指南:让你的查询速度飞起来
· 本地搭建一个对嘴AI工具
· 我用这13个工具,让开发效率提升了5倍!
· 总结下参与以及看到的一些好的业务设计的 pattern
· 商品中心—15.库存分桶扣减的技术文档