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

因此你会发现,每个合法的状态都能被分成两个合法的子结构,因此可以考虑使用区间 \(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. Jenkins+Sonar质量门禁【实践篇-maven版】

    Jenkins+Sonar质量门禁[实践篇-maven版] 配置文档百度挺多的,就不展开来了 首先很遗憾的告诉大家,maven版做不了质量门禁!只能扫描!!!     就我们公司项目里,jenkins ...

  2. 第十七个知识点:描述和比较DES和AES的轮结构

    第十七个知识点:描述和比较DES和AES的轮结构 这是密码学52件事中的第17篇.本周我们描述和比较DES和AES的结构. DES和AES都是迭代分组密码的例子.分组密码通过重复使用一个简单的轮函数来 ...

  3. CS5213设计HDMI转VGA带音频方案+设计电路|直接替代AG6200 AG6201

    台湾安格AG6200 AG6201专门用于设计HDMI转VGA带音频输出的方案芯片,CS5213是一款HDMI to VGA转换器且结合了HDMI输入接口和模拟RGB DAC输出.带支持片上音频数模转 ...

  4. 高效位运算 __builtin_系列函数

    •int __builtin_ffs (unsigned int x) 返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4. •int __builtin_clz ...

  5. Android物联网应用程序开发(智慧城市)—— 火焰监控界面开发

    效果: 布局代码: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns: ...

  6. LCA/在线(倍增)离线(Tarjan)

    概念 祖先 公共祖先 最近公共祖先 方法1:暴力爬山法 方法2:倍增 求公共祖先 求俩点的距离 Tarjan 概念 祖先 有根树中,一个节点到根的路径上的所有节点被视为这个点的祖先,包括根和它本身 公 ...

  7. Zabbix监控报警Lack of free swap space on Zabbix server解决办法

    故障描述: Lack of free swap space on Zabbix server 故障原因: 情况一:云主机:因为Zabbix监控没有考虑虚拟主机的swap分区情况. 情况二:物理主机:说 ...

  8. 本地Java大数据环境基础配置(Maven)

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6812623309138559500/ 创建项目 准备pom.xml文件配置(附在文档最后) 在下载jar过程中极其 ...

  9. 解决maven每次更新都编程java1.5

    Maven: 每次更新Maven Project ,JAVA 版本都变为1.5 本文转载自:http://www.cnblogs.com/Hxinguan/p/6132446.html 问题: 1.创 ...

  10. SSM实现支付宝支付

    学习支付宝支付 一.支付宝测试环境代码测试 1.下载电脑网站的官方demo: 下载地址:https://docs.open.alipay.com/270/106291/ 2.下载解压导入eclipse ...