F 连通性状压dp
思路
看了dls的讲解后才明白一点点。
状态\(dp[i][j][k]\)表示到表示到i列,删除了j条边,点i和n-1+i是否联通,对于下一列点,
若当前i和n-1+i连通,则多出来的三条边连任意两条,使得下一列点i+1和n+i连通,否则下一列点不连通。
若当前点i和n-1+i不连通,则分情况:设上面横着的边为p1,下面横着的边为p2,最右边竖着的边为p3,首先p1和p2是必须连的(这个我想不通,可能是限制最多两个连通块),p3决定下一列点的连通性。
代码
void update(int &a,int b)
{
a+=b;
if(a>=mod) a-=mod;
}
void solve()
{
cin>>n>>p;
f[0][1][0]=f[0][0][1]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
for(int k=0;k<2;k++)
{
if(!f[i][j][k]) continue;
for(int x=1;x<8;x++)
{
int p1=(x>>0)&1,p2=(x>>1)&1,p3=(x>>2)&1;
if(k==0&&(!p1||!p2)) continue;
if(k==0) update(f[i+1][j+1-p3][p3],f[i][j][k]);
if(k==1&&(!p1&&!p2)) continue;
if(k==1) update(f[i+1][j+3-p1-p2-p3][(p1+p2+p3)>=2],f[i][j][k]);
}
}
}
}
for(int i=1;i<n;i++) cout<<f[n-1][i][1]<<" ";
cout<<endl;
}
- 性状 Beginner AtCoder Contest 248性状beginner atcoder contest contest programming beginner atcoder beginner atcoder contest 296 beginner atcoder contest 295 beginner atcoder contest abcde beginner atcoder contest 335 beginner atcoder contest 328 beginner atcoder contest 334 beginner atcoder contest 332 beginner atcoder contest 315