@hdu - [email protected] Rigid Frameworks

目录

  • @[email protected]
  • @[email protected]
  • @accepted [email protected]
  • @[email protected]

@[email protected]

如果对于一个平面图,将边看成火柴棍,将点看成用橡皮筋将木棍的头绑在一起(请自行脑补)。如果这个平面图不能够改变形状,称这个平面图为刚体图。

如下图中只有 D 不是刚体图。

给定一个 n*m 的方格图,你可以在某些方格的对角线上加支撑木棍以保持它的形状不变。

问让一个 n*m 的方格图变为刚体图,添加支撑木棍的方案数是多少?

下图展现了一个 2*3 的方格图以及它不是刚体图的原因。

下图展现了一个让 2*3 的方格图变为刚体图的方案:

input
多组数据。每组数据只包含一行两个整数 n, m 描述方格图的大小

output
对于每组数据,输出方案数 mod 10^9 + 7。

sample input
1 2
3 2
7 9
10 10
sample output
4
448
357533852
935300639

@[email protected]

自我脑补一下,可以发现一个正方形将它拖过来拖过去,也只能变成平行四边形。
即:无论怎么变化,它的对边始终平行。
相当于每一行的竖边的相对位置关系、每一列的横边的相对位置关系是确定的(即平行)。

考虑在一个正方形内加支撑,则它的横边与竖边就变为垂直的了。
又因为平行具有传递性,会将垂直关系传递。所以这个正方形所在的行的每一条竖边与所在的列的每一条横边垂直。
相当于一个正方形内加支撑,它所在的行与列就有了相对的位置关系。

不难发现方格图是刚体图与它所有的行与列互相之间都有相对的位置关系是等价的。
于是我们考虑以行、列建二分图,则相当于询问该二分图连通的方案数。

求连通方案很显然是容斥,即用总方案数减去不连通的数量。同时因为是二分图,所以可以不使用状压 dp 来做。
定义 dp[i][j] 表示左边 i 个点与右边 j 个点连通的方案数。
因为边有两类(对角线有两种),总方案数为 3^(i*j)。
再考虑不连通时与左边的点 1 连通的连通块,可得状态转移(注意左边的点 1 必须要选):
\[dp[i][j] = 3^{i*j}-\sum_{p\le i,q\le j}3^{(i-p)*(j-q)}*dp[p][q]*C_{i-1}^{p-1}*C_{j}^{q}\]

然后 O(n^4) 做个 dp 即可

@accepted [email protected]

#include<cstdio>
const int MOD = int(1E9) + 7;
const int MAXN = 10;
int dp[MAXN + 5][MAXN + 5], comb[MAXN + 5][MAXN + 5], pw[MAXN*MAXN + 5];
void init() {
    for(int i=0;i<=MAXN;i++) {
        comb[i][0] = 1;
        for(int j=1;j<=i;j++)
            comb[i][j] = (comb[i-1][j] + comb[i-1][j-1])%MOD;
    }
    pw[0] = 1;
    for(int i=1;i<=MAXN*MAXN;i++)
        pw[i] = 3LL*pw[i-1]%MOD;
    for(int i=0;i<=MAXN;i++)
        for(int j=0;j<=MAXN;j++)
            dp[i][j] = pw[i*j];
    for(int i=0;i<=MAXN;i++)
        for(int j=0;j<=MAXN;j++)
            for(int l=0;l<=i-1;l++)
                for(int k=0;k<=j;k++) {
                    if( l == i-1 && k == j ) continue;
                    dp[i][j] = (dp[i][j] + MOD - 1LL*pw[(i-l-1)*(j-k)]*dp[l+1][k]%MOD*comb[i-1][l]%MOD*comb[j][k]%MOD)%MOD;
                }
}
int main() {
    int n, m; init();
    while( scanf("%d%d", &n, &m) == 2 )
        printf("%d\n", dp[n][m]);
}

@[email protected]

刚体。。。说实话我还真不知道是啥。。。
所以题意的理解卡了很久。。。

然后看到 n, m 这么小想可不可以写一个插头 dp 啥的,写着写着把自己 hack 掉了。。。
你告诉 n, m <= 10 然后跑一个 O(n^4) 的算法?这个数据范围。。。是用来误导人的嘛。。。

不过这个题的建模还是挺有趣。

原文地址:https://www.cnblogs.com/Tiw-Air-OAO/p/11122815.html

时间: 2024-08-28 22:37:54

@hdu - [email protected] Rigid Frameworks的相关文章

@hdu - [email&#160;protected] Problem A.Alkane

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 求包含 n 个碳的烷烃与烷基的同分异构体个数 mod 998244353. 如果你没学过有机化学,你可以认为烷烃是 n 个点且每个点度数 <= 4 的无根树:烷基是 n 个点且每个点儿子个数 <= 3 的有根树. 原题传送门. @[email protected] 先考虑有根树的情况

@hdu - [email&#160;protected] Function

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定 n,求: \[\sum_{i=1}^{n}gcd(\lfloor^3\sqrt{i}\rfloor, i)\mod 998244353\] Input 第一行包含一个整数 T(1≤T≤11) 描述数据组数. 接下来 T 行,每行一个整数 n (1≤n≤10^21) 描述询问. O

@hdu - [email&#160;protected] Paint Pearls

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个长度为 n 的序列,每一个位置有一个目标颜色,初始所有位置都没有颜色. 每次操作可以选择一个区间,将这个区间内的位置的颜色改为其目标颜色,代价是区间内不同的目标颜色数量^2. 求将所有位置改为目标颜色的最小代价. Input 多组数据. 每组数据第一行一个整数 n(1 ≤ n

@hdu - [email&#160;protected] Subsequence

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定如下计算序列权值的函数: 对于一个由三元组 (cost0, cost1, color) 组成的序列 A,求通过以上函数计算出来的第 k 大的子序列的权值. Input 第一行一个整数 t,表示数据组数. 对于每组数据,第一行包含两个整数 n, k. 接下来 n 行,每行三个整数 c

@hdu - [email&#160;protected] Counting Stars

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个 n 点 m 边的无向图(无重边自环),求有多少子图形如,包含 4 个点 {A, B, C, D} 与 6 条边 {AB, BC, CD, DA, AC}. 原题链接. @[email protected] 一个并不常用的黑科技:三元环计数. mark一下博客地址. 注意到题目

TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::[email&#160;protected] 转换为 spark.core.IViewport。

1.错误描述 TypeError: Error #1034: 强制转换类型失败:无法将 mx.controls::[email protected] 转换为 spark.core.IViewport. at mx.binding::Binding/defaultDestFunc()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\binding\Binding.as:270] at Function/http://adobe.com/AS3/2

$*和[email&#160;protected]之间区别代码分析

#!/bin/bash set 'apple pie' pears peaches for i in $*           /*单引号被去掉,循环单个字符输出*/ do echo $i done [[email protected] Ex_14.02-14.31]# sh 14-14-1 apple pie pears peaches -------------------------------------------------------------- #!/bin/bash set

[email&#160;protected]一个高效的配置管理工具--Ansible configure management--翻译(六)

无书面许可请勿转载 高级playbook Finding files with variables All modules can take variables as part of their arguments by dereferencing them with {{ and }} . You can use this to load a particular file based on a variable. For example, you might want to select a

【转载】 ERROR 1045 (28000): Access denied for user [email&#160;protected] (using password: NO)

来自:http://www.jb51.net/LINUXjishu/10981.html 错误描述: Mysql中添加用户之后可能出现登录时提示ERROR 1045 (28000): Access denied for user的错误.删除user.user中值为NULL的,或更新NULL为test 1)delete from user where user is NULL 2)update user set user='test' where user is NULL.意外的情况: 如果上述方