【学习笔记】[AGC039E] Pairing Points

太复杂了,做不动。

设第 2 n 2n 2n个点与 k k k相连,这样把点分成了左右两个集合,一定存在左边的 x x x与右边的 y y y相连的一条边,并且这个结构有一个比较优美的性质,左右相连的边的点的编号应该是单调,否则会存在环。那么我们取最靠近上端的那条边。

那么我们用 [ i : j ] ( k ) [i:j](k) [i:j](k)表示 [ i : j ] [i:j] [i:j]这一段圆弧, k k k向圆弧外的一个点连了边的方案数。如果我们直接将问题拆分成 [ i : k − 1 ] ( x ) [i:k-1](x) [i:k1](x) [ k + 1 : j ] ( y ) [k+1:j](y) [k+1:j](y)那么显然这样的方案是合法的,因为任意一条边都能和 ( x , y ) (x,y) (x,y)互达并且不存在环。显然我们只遗漏了 x x x下端点和 y y y下端点连边的情况,而我们事实上可以选择一条割线,使得将 ( ? , k ) (?,k) (?,k)删去后变成不连通的两部分,更形象的讲,删去 ( ? , k ) (?,k) (?,k)后与 ( x , y ) (x,y) (x,y)联通的一定是上端两段圆弧,那么枚举 p p p, q q q,显然 p p p, q q q上端只存在 ( x , y ) (x,y) (x,y)一条横边,那么可以拆分成 [ i : p ] ( x ) [i:p](x) [i:p](x) [ q : j ] ( y ) [q:j](y) [q:j](y),下端圆弧因为不存在向上的边因此直接拆成 [ p + 1 : q − 1 ] ( k ) [p+1:q-1](k) [p+1:q1](k)

复杂度 O ( n 7 ) O(n^7) O(n7)。据说常数极小。

#include<bits/stdc++.h> #define ll long long #define pii pair<int,int> #define fi first #define se second #define pb push_back #define db long double #define cpx complex<db> using namespace std; int n; char a[45][45]; ll dp[45][45][45],res; ll dfs(int i,int j,int k){ if(k<i||k>j)return 0; if(i==j)return 1; if(i==k||j==k)return 0; if(~dp[i][j][k])return dp[i][j][k]; ll res(0); for(int x=i;x<k;x++){ for(int y=k+1;y<=j;y++){ if(a[x][y]=='1'){ for(int p=x;p<k;p++){ for(int q=k+1;q<=y;q++){ res+=dfs(i,p,x)*dfs(q,j,y)*dfs(p+1,q-1,k); } } } } } return dp[i][j][k]=res; } int main(){ memset(dp,-1,sizeof dp); scanf("%d",&n),n<<=1; for(int i=1;i<=n;i++){ scanf("%s",a[i]+1); }for(int i=1;i<n;i++)if(a[n][i]=='1')res+=dfs(1,n-1,i); printf("%lld",res); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530059.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(17)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示