首先可以发现的是,因为两条线段不能在除了端点处相交,因此整个多边形最终一定会被连接成最上方由若干条线段在端点处相交连成,每条线段下方又是一个子结构。

因此你会发现,每个合法的状态都能被分成两个合法的子结构,因此可以考虑使用区间 \(dp\) 来解决这个问题。

首先,我们简单地考虑令 \(dp_{i, j}\) 表示只使用 \(i, j\) 这个区间之间的边将 \(i, j\) 这个区间联通的方案。

  • 直接在 \(i, j\) 之间连边。

那么枚举每个 \(k\) 做为中间的断点,那么就有转移:

\[dp_{i, j} = \sum\limits_{k = i} ^ {j - 1} dp_{i, k} \times dp_{k + 1, j}(a_{i, j} = 1)
\]
  • 不直接在 \(i, j\) 之间连边。

同样考虑枚举中间的端点 \(k\),那么一个合法的方案就会被描述为用 \(i \sim k\) 之间的边联通 \(i \sim k\) 另一边类似,于是有转移:

\[dp_{i, j} = \sum\limits_{k = i + 1} ^ {j - 1} dp_{i, k} \times dp_{k, j}
\]

但其实你会发现,同一个断点的方案会被所有最外层线段交点的位置计算一次,那么一个最简单的想法就是让这个方案只被计算一次。

于此同时你可以发现我们目前只会计算直接连接两个端点的方案,因此让这个方案在左上边第一个线段交点的位置计算一次是一个不赖的选择。

因此我们需要改写一下 \(dp\) 的状态,令 \(dp_{i, j, 0 / 1}\) 分别表示直接连接 \(i, j\) 和不直接连接 \(i, j\) 的方案。

那么这里的转移就应该变为:

\[dp_{i, j, 1} = \sum\limits_{k = i + 1} ^ {j - 1} (dp_{i, k, 0} + dp_{i, k, 1}) \times dp_{k, j, 0}
\]

对应地改写第一条转移方程即可。

复杂度 \(O(n ^ 3)\)。

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, r) for (int i = l; i <= r; ++i)
const int N = 500 + 5;
const int Mod = 1e9 + 7;
int n, a[N][N], f[N][N], dp[N][N][2];
int read() {
char c; int x = 0, f = 1;
c = getchar();
while (c > '9' || c < '0') { if(c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int Inc(int a, int b) { return (a += b) >= Mod ? a - Mod : a;}
int Mul(int a, int b) { return 1ll * a * b % Mod;}
int main() {
n = read();
rep(i, 1, n) rep(j, 1, n) a[i][j] = read();
rep(i, 1, n) dp[i][i][1] = f[i][i] = 1;
rep(i, 1, n) dp[i][i + 1][0] = f[i][i + 1] = a[i][i + 1];
rep(len, 3, n) rep(i, 1, n) {
int j = i + len - 1; if(j > n) break;
rep(k, i, j - 1) if(a[i][j]) dp[i][j][0] = Inc(dp[i][j][0], Mul(f[i][k], f[k + 1][j]));
rep(k, i + 1, j - 1) dp[i][j][1] = Inc(dp[i][j][1], Mul(f[i][k], dp[k][j][0]));
f[i][j] = Inc(dp[i][j][0], dp[i][j][1]);
}
printf("%d", f[1][n]);
return 0;
}

值得一提的是,\(dp\) 的转移一定要想办法将这个问题拆解成已经解决的子问题的结构,例如区间 \(dp\) 中就一定要能描述为左右两个合法区间的结合或其他的意义。

CF888F Connecting Vertices的更多相关文章

  1. Connecting Vertices CodeForces - 888F (图论,计数)

    链接 大意: 给定邻接表表示两点是否可以连接, 要求将图连成树, 且边不相交的方案数 n范围比较小, 可以直接区间dp $f[l][r]$表示答案, $g[l][r]$表示区间[l,r]全部连通且l, ...

  2. POJ Minimum Cut

    Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 9302   Accepted: 3902 Case ...

  3. POJ 2914 Minimum Cut

    Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 9319   Accepted: 3910 Case ...

  4. 论文笔记之:Large Scale Distributed Semi-Supervised Learning Using Streaming Approximation

    Large Scale Distributed Semi-Supervised Learning Using Streaming Approximation Google  2016.10.06 官方 ...

  5. CodeForces 682C Alyona and the Tree (树+dfs)

    Alyona and the Tree 题目链接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/C Description Alyona ...

  6. POJ_2914_Minimum_Cut_(Stoer_Wagner)

    描述 http://poj.org/problem?id=2914 求无向图中最小割. Minimum Cut Time Limit: 10000MS   Memory Limit: 65536K T ...

  7. POJ 2914 Minimum Cut 最小割图论

    Description Given an undirected graph, in which two vertices can be connected by multiple edges, wha ...

  8. Shorten Diameter

    Shorten Diameter Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB Score : 600 points P ...

  9. 2015 多校联赛 ——HDU5302(构造)

    Connect the Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

随机推荐

  1. 【Java】质数判断

    static boolean isPrime(int n) { if(n<=1) { return false; } if(n==2||n==3) { return true; } if(n%6 ...

  2. VAE with a VampPrior

    目录 概 主要内容 分级的VAE 代码 Tomczak J. & Welling M. VAE with a VampPrior. In International Conference on ...

  3. CS5211替代兼容PS8625|普瑞PS8625替代方案|CapstoneCS5211

    PS8625是一个DP显示端口 到LVDS转换器芯片,利用GPU和显示端口(DP) 或嵌入式显示端口(eDP) 输出和接受LVDS输入的显示面板.PS8625实现双通道DP输入,双链路LVDS输出.P ...

  4. 数据可视化 gojs 简单使用介绍

    目录 1. gojs 简介 2. gojs 应用场景 3. 为什么选用 gojs: 4. gojs 上手指南 5. 小技巧(非常实用哦) 6. 实践:实现节点分组关系可视化交互图 最后 本文是关于如何 ...

  5. 使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态。点击列表的项,切换二级列表的显示或隐藏状态

    查看本章节 查看作业目录 需求说明: 使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态.点击列表的项,切 ...

  6. pod内执行kill -3 pid

    1.使用logs命令监控输出 kubectl logs iothub2-iop-dm-replicaset-0   -n iot  -f  >> yuanqianqian.txt 2.在p ...

  7. docker安装elasticsearch6.8.3-单机模式及可视化Kibana6.8.3

    docker安装elasticsearch6.8.3-单机模式 拉取镜像 docker pull elasticsearch:6.8.3 创建容器  测试环境加上-e "discovery. ...

  8. java单元测试调用mybatis接口并执行

    今天想使用单元测试类,存储一些数据到mysql,可是,一直在报错,org.springframework.beans.factory.NoSuchBeanDefinitionException: No ...

  9. 第10组 Beta冲刺 总结

    1.基本情况 组长博客链接:https://www.cnblogs.com/cpandbb/p/14050808.html 答辩总结: ·因为alpha阶段的产品做得偏离了方向,所以beta冲刺大家非 ...

  10. mysql按照时间分组查询

    mysql 按年.月.周.日分组查询 1.按照年份分组查询 SELECT DATE_FORMAT(t.bill_time,'%Y') month_time,sum(t.pay_price) total ...