Connecting Vertices

Connecting Vertices

题解

由于整个图形是一个正N边形,很容易发现,连接一条(i,j)的边,相当于将ij两侧的点隔开,使其无法连接。

于是,我们就自然而然的想到了区间dp。

但是由于这是一个环,我们还需要将其剖成一条链,而在链上的线段,是不可以相交的。

我们设f_{l,r,0}为要连接(l,r)的方案数,f_{l,r,1}为不连接(l,r)的方案数。

两者都可以通过断点的枚举进行转移,

f_{l,r,0}=\sum(f_{l,k,0}+f_{l,k,1})(f_{k+1,r,0}+f_{k+1,r,1})

f_{l,r,1}=\sum f_{l,k,0}(f_{k,r,0}+f_{k,r,1})

\left [ l,r \right ]区间之间的连接为f_{l,r,0}+f_{l,r,1},最后答案即为f_{1,n,0}+f_{1,n,1}

源码

#include
using namespace std;
typedef long long LL;
const LL INF=0x7f7f7f7f7f7f;
const LL mo=1000000007;
#define gc() getchar()
template
void read(_T &x){
	_T f=1;x=0;char s=gc();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=gc();}
	while(s>='0'&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=gc();}
	x*=f;
}
template
_T Fabs(_T x){return x<0?-x:x;}
LL n,dp[505][505][2];
bool a[505][505];
signed main(){
	read(n);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			read(a[i][j]);
	for(int i=1;i<=n;i++)dp[i][i][0]=1;
	for(int i=1;i

谢谢!!!

你可能感兴趣的:(#,区间dp)