SRM566 1000pts

绍一的模拟赛题

【题意】

小Z养了𝑚(50)只企鹅,第i只企鹅的坐标为(xi,yi),颜色为𝑐𝑖。出于对企鹅安全的考虑,他决定造栅栏。地面上有𝑛(200)个桩,编号0...𝑛1,小Z会用一些直的栅栏,每个栅栏连接某两个桩子。对于最后的结果,任意两个栅栏不能交叉。任意一个桩只能连接0个或2个栅栏,栅栏必须围成一些封闭的多边形。由于经费有限,每一个多边形内至少包含一只企鹅。小Z的企鹅有着许多颜色。相同颜色的企鹅必须在同一个多边形内。为了保证所有企鹅的安全,每一只企鹅都必须被包含在某一个多边形内。

各种不合法的情况:

某种合法的情况:


现在小Z想知道自己有多少种合法的不同的造栅栏的方案𝑎𝑛𝑠。

 

【题解】

用ℎ[𝑙][𝑟][0..1]表示𝑙, 𝑟必须选,点的编号在𝑙, 𝑟之间,最外层的多边形内没有(0)或有(1)企鹅的除了最外层多边形其他多边形均合法的方案数。𝑔[𝑙][𝑟]表示𝑙必须选,点的编号在𝑙, 𝑟之间合法的方案数。𝑓[𝑙][𝑟]表示,点的编号在𝑙, 𝑟之间合法的方案数。当一个栅栏两侧没有相同颜色的企鹅时定义这
个栅栏是有效的。

然后就可以直接区间DP了。考虑计算ℎ[𝑙][𝑟][𝑛𝑜𝑤],枚举中间点𝑛𝑙,当< 𝑛𝑙, 𝑙 >合法时进行转移,分类讨论𝑛𝑜𝑤和三角形(𝑙, 𝑛𝑙, 𝑟)中有没有点的情况,再考虑向量< 𝑙, 𝑛𝑙 >右侧有没有企鹅,没有直接转移,有的话,考虑多边形(𝑙, 𝑙 + 1, 𝑛𝑙 − 1, 𝑛𝑙)内有没有点分类讨论一下即可。考虑计算𝑔[𝑙][𝑟],枚举中间点𝑛𝑟,当< 𝑛𝑟, 𝑙 >合法时进行转移,如果向量< 𝑟, 𝑙 >左侧和向量< 𝑙, 𝑛𝑙 >左侧的企鹅的并集为空𝑔[𝑙][𝑟] += ℎ[𝑙][𝑛𝑟][1],否则如果向量< 𝑛𝑟 + 1, 𝑟 >的企鹅和上面两个的并集为空𝑔[𝑙][𝑟] += ℎ[𝑙][𝑛𝑟][1] * 𝑓[𝑛𝑟 + 1][𝑟]。𝑓[𝑙][𝑟]可以轻松的从𝑔[𝑙][𝑟]转移过来。

【分析】

题解非常地神,直接给出了一个dp,这里从头分析为什么要这么做。

首先很容易确定一条边是否可以选(如果这条边两侧有相同颜色的企鹅,那么不能选)

那么现在问题变成了知道一些边能选不能选,要求选择一些边使得它们围成多个多边形,且每个企鹅都在一个多边形里,每个多边形里都有至少一个企鹅。
问题是在一个环上选出一些边,怎么就变成区间dp了呢?

考虑最朴素的暴力:枚举每条边选不选,再检查是否满足条件。所以第一步,我们考虑枚举一条边,选择任意一个点作为起始点,如下图选择了这个绿色的点

为了不重复,我们枚举这个点沿逆时针方向遇到的第一个有边的点。具体地说,这个点可能有边,可能没有边,如果没有边,我们按逆时针顺序继续枚举下一个点,直到枚举到一个有边的点,标为蓝色。

接下来继续枚举第二的点作为边的另一端,同样的,为了不重复,这个点从r开始按顺时针顺序枚举,找到第一个与i有边的j,由于i是从l开始第一个有边的点,所以[l,i+1]里面的点都不会再有边了,而[j+1,r]里点只有它们内部才可能有边,所以<i,j>这条边只能与[i+1,j1]里面的点构成多边形了。而这恰好是一个区间,所以可以考虑区间dp。我们现在关心的是什么?是[i,j]这段区间里,能形成多少种如红线的方案。具体来说就是选了某些边,且i,j都已经作为一个端点,这样就可以在添加了<i,j>之后合并了,记方案数为h(i,j)(暂时不考虑企鹅的限制),那么此时答案需要加上h(i,j)([j+1,r])

再来看[j+1,r]里连边的方案数怎么求,我们发现这又是可以看成一个环,我们又回到了一个和原来的问题一样的问题,可以用同样的方式求解,不妨用f(l,r)表示,这样答案就是f(0,n1)

现在我们考虑h(l,r)怎么求,同样的,我们可以枚举l出去的第一条边<l,i>

那么现在有两种情况:

1.<i,r>之间有边,这样的方案数就是f(l+1,i1)f(i+1,r1)

2.<i,r>之间没有边,这样的方案数是h(i,r)f(l+1,i1)

至此,在忽略[每个企鹅都在一个多边形里,每个多边形里都有至少一个企鹅]这个限制的情况下,我们已经可以在O(n4)解决这个问题了。

我们发现求解h的复杂度是O(n3)的,而求解f是O(n4)的,所以考虑优化f的转移。

我们发现f(l,r)=liri<jrh(i,j)f(j+1,r)

f(l1,r)=l1iri<jrh(i,j)f(j+1,r)

对于lir的部分,两个状态是一样的,所以我们自然不必每次都枚举。

一种思路是记e(l,r)=l<jrh(l,j)f(j+1,r)

f(l,r)=lire(i,j)

e可以理解为l一定选的情况下[l,r]内的方案数。

这样f,h,e可以在O(n)的时间内转移,总时间复杂度O(n3).

 

现在是时候考虑[每个企鹅都在一个多边形里,每个多边形里都有至少一个企鹅]这个限制了。

实际上也很简单,我们只要保证在闭合一个多边形的时候它里面有企鹅,并且在转移的时候保证空出来的图形里没企鹅即可。

这需要在h的状态里记录这个未封闭的图形里是否有企鹅,在转移f的时候保证S1没有企鹅,在转移h时保证S2没企鹅,在通过连接<i,r>转移h的时候保证S3没有企鹅。

 

 

我为什么用了f,h,e却不用g呢?因为在代码里g(l,r)表示连了<l,r>这条边[l,r]内的方案数,实际上就是h(l,r,1)

现在来回答开头的问题

在环上选点是如何变成了区间dp?

【notice】 mod 100007是会爆int的,一开始注意到了写程序的时候却先忽略了,后来查了半天还以为转移写错了。。

【代码】

 

 

posted @   Showson  阅读(328)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示