Codeforces 题面传送门 & 洛谷题面传送门

hot tea 一道。

首先我们考虑这个奇奇怪怪的最小割有什么等价的表达。不难发现,如果我们选择了 \(S\to T\) 这条边并加入了一个新的节点 \(u\),那么就会出现两条边 \(S\to u,u\to T\)。我们考虑把 \(S\) 和 \(u\) 分别当作新的源点和汇点重复上面的过程,假设 \(S\to u\) 产生的流量为 \(f_1\),我们再把 \(u,T\) 也分别当作新的源汇并产生 \(f_2\) 的流量,那么新产生的这个节点 \(u\) 对原图的最小割,即最大流产生了 \(\min(f_1,f_2)\) 的贡献。也就是说,当我们选择 \(S\to T\) 这条边并新添了一个点 \(u\),就等价于将原问题拆成了 \(S\to u\) 和 \(u\to T\) 两个子问题求解,这就天然地形成了 DP 的模型。

考虑 \(f_{n,m}\)​​ 表示对于一张初始只有 \(S,T\)​​ 两个点和一条边 \(S\to T\)​​ 的图进行 \(n\)​​​ 次操作后能够得到多少张最小割为 \(m\)​​ 的图,再设 \(g_{n,m}\)​​ 表示对于一张初始有三个点 \(S,T,u\)​​ 和两条边 \(S\to u\)​​ 和 \(u\to T\)​​ 的图在进行 \(n-1\)​​ 次操作后可以得到多少个最小割为 \(m\)​​ 的图,转移就考虑对 \(S\to u\)​​ 长出的子图和 \(u\to T\)​​ 长出的子图分别进行了多少次操作,设为 \(k\)​ 和 \(n-1-k\)​,那么转移就是一个 \(\min\)​ 卷积的形式,即 \(g_{n,m}=\sum\limits_{k=0}^{n-1}\sum\limits_{\min(x,y)=m}f_{k,x}f_{n-1-k,y}\)​,众所周知,\(\min\)​ 卷积可以通过处理后缀和做到线性,即假设 \(sf_{n,m}\)​ 为 \(f_{n,m}\)​ 的后缀和,\(sg_{n,m}\)​ 也同理,那么 \(sg_{n,m}=\sum\limits_{k=0}^{n-1}sf_{k,m}sf_{n-1-k,m}\)​,再一遍差分即可求出真正的 \(g\)。这样我们就实现了 \(f\to g\)​。

接下来考虑怎样 \(g\to f\),方便起见,我们将所有 \(S\to u,u\to T\) 进行 \(n-1\) 次操作得到的最小割为 \(m\) 的图称作一个“\((n,m)\) 结构”,将所有 \((n,m)\) 结构的总体称作“\((n,m)\) 类”,那么我们考虑一个背包的思想,考虑所有 \((i,j)\) 类对 \(f_{n,m}\) 的贡献,那么我们枚举用了多少个 \((i,j)\) 类中的结构,设为 \(k\),那么有转移 \(f_{n,m}\leftarrow f_{n-ki,m-kj}·\dbinom{g_{i,j}+k-1}{k}\),其中后面那个组合数可以用隔板法来解释,具体来说就是设 \((i,j)\) 类第 \(t\) 个结构出现了 \(x_t\) 次,那么由于“经过置换得到的图视为相同”这一条件的存在,一组 \((x_1,x_2,\cdots,x_{g_{i,j}})\) 就能唯一确定一张图,方案数就是 \(x_1+x_2+\cdots+x_{g_{i,j}}=k\) 的解的个数,根据隔板法可知该值等于 \(\dbinom{g_{i,j}+k-1}{k}\)。

还有一个小问题就是 DP 转移的顺序,如果我们不钦定 DP 转移的顺序就会算重。因此我们考虑从小到大枚举 \(i\) 再从小到大枚举 \(j\),算出 \(g_{i,j}\) 之后再用多重背包的方式松弛所有 \(f_{n,m}\),不难发现这样我们肯定会按照 \((i,j)\) 这样的二元组的字典序顺序进行多重背包,也就不会担心算重的问题了。这就有点类似于子集卷积那种“半在线”的感觉,学过子集卷积/半在线卷积的应该会比较好理解。

时间复杂度上界大概是 \(n^4\ln n\),因为后面枚举 \(k\) 那一维复杂度大概是调和级数的。

const int MAXN=50;
const int MOD=1e9+7;
int n,m,f[MAXN+5][MAXN+5],sf[MAXN+5][MAXN+5],g[MAXN+5][MAXN+5],sg[MAXN+5][MAXN+5];
int inv[MAXN+5];
int main(){
scanf("%d%d",&n,&m);f[0][1]=sf[0][1]=1;
for(int i=(inv[0]=inv[1]=1)+1;i<=MAXN;i++) inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++) for(int k=0;k<=i-1;k++)
sg[i][j]=(sg[i][j]+1ll*sf[k][j]*sf[i-1-k][j])%MOD;
for(int j=1;j<=n+1;j++) g[i][j]=(sg[i][j]-sg[i][j+1]+MOD)%MOD;
// for(int j=1;j<=n+1;j++) printf("g %d %d %d\n",i,j,g[i][j]);
for(int j=1;j<=n+1;j++){
for(int k=n+1;k;k--) for(int l=n+1;l;l--){
int mul=1;
for(int t=1;t*i<=k&&t*j<=l;t++){
mul=1ll*mul*(g[i][j]+t-1)%MOD*inv[t]%MOD;
f[k][l]=(f[k][l]+1ll*f[k-t*i][l-t*j]*mul)%MOD;
}
}
}
for(int j=n+1;j;j--) sf[i][j]=(sf[i][j+1]+f[i][j])%MOD;
} printf("%d\n",f[n][m]);
return 0;
}

Codeforces 848D - Shake It!(DP)的更多相关文章

  1. Codeforces Gym101341K:Competitions(DP)

    http://codeforces.com/gym/101341/problem/K 题意:给出n个区间,每个区间有一个l, r, w,代表区间左端点右端点和区间的权值,现在可以选取一些区间,要求选择 ...

  2. codeforces 711C Coloring Trees(DP)

    题目链接:http://codeforces.com/problemset/problem/711/C O(n^4)的复杂度,以为会超时的 思路:dp[i][j][k]表示第i棵数用颜色k涂完后bea ...

  3. codeforces#1154F. Shovels Shop (dp)

    题目链接: http://codeforces.com/contest/1154/problem/F 题意: 有$n$个物品,$m$条优惠 每个优惠的格式是,买$x_i$个物品,最便宜的$y_i$个物 ...

  4. Codeforces 1051 D.Bicolorings(DP)

    Codeforces 1051 D.Bicolorings 题意:一个2×n的方格纸,用黑白给格子涂色,要求分出k个连通块,求方案数. 思路:用0,1表示黑白,则第i列可以涂00,01,10,11,( ...

  5. Codeforces 1207C Gas Pipeline (dp)

    题目链接:http://codeforces.com/problemset/problem/1207/C 题目大意是给一条道路修管道,相隔一个单位的管道有两个柱子支撑,管道柱子高度可以是1可以是2,道 ...

  6. Codeforces 704C - Black Widow(dp)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 感觉这种题被评到 *2900 是因为细节太繁琐了,而不是题目本身的难度,所以我切掉这种题根本不能说明什么-- 首先题目中有一个非 ...

  7. Codeforces 682B New Skateboard(DP)

    题目大概说给一个数字组成的字符串问有几个子串其代表的数字(可以有前导0)能被4整除. dp[i][m]表示字符串0...i中mod 4为m的后缀的个数 通过在i-1添加str[i]字符转移,或者以st ...

  8. Codeforces 543D Road Improvement(DP)

    题目链接 Solution 比较明显的树形DP模型. 首先可以先用一次DFS求出以1为根时,sum[i](以i为子树的根时,满足要求的子树的个数). 考虑将根从i变换到它的儿子j时,sum[i]产生的 ...

  9. Codeforces 543C Remembering Strings(DP)

    题意比较麻烦 见题目链接 Solution: 非常值得注意的一点是题目给出的范围只有20,而众所周知字母表里有26个字母.于是显然对一个字母进行变换后是不影响到其它字符串的. 20的范围恰好又是常见状 ...

随机推荐

  1. 2021能源PWN wp

    babyshellcode 这题考无write泄露,write被沙盒禁用时,可以考虑延时盲注的方式获得flag,此exp可作为此类型题目模版,只需要修改部分参数即可,详细见注释 from pwn im ...

  2. 基于Apache Hudi 的CDC数据入湖

    作者:李少锋 文章目录: 一.CDC背景介绍 二.CDC数据入湖 三.Hudi核心设计 四.Hudi未来规划 1. CDC背景介绍 首先我们介绍什么是CDC?CDC的全称是Change data Ca ...

  3. 面试题系列:new String("abc")创建了几个对象

    new String("abc")创建了几个对象 面试官考察点猜想 这种问题,考察你对JVM的理解程度.涉及到常量池.对象内存分配等问题. 涉及背景知识详解 在分析这个问题之前,我 ...

  4. Spring DeferredResult 异步请求

    Spring DeferredResult 异步请求 一.背景 二.分析 三.实现要求 四.后端代码实现 五.运行结果 1.超时操作 2.正常操作 六.DeferredResult运行原理 六.注意事 ...

  5. FastAPI 学习之路(二十八)使用密码和 Bearer 的简单 OAuth2

    OAuth2 规定在使用(我们打算用的)「password 流程」时,客户端/用户必须将 username 和 password 字段作为表单数据发送.我们看下在我们应该去如何实现呢. 我们写一个登录 ...

  6. 学习手册 | MySQL篇 · 其一

    InnoDB关键特性 插入缓冲(Insert Buffer) 问题:   在InnoDB插入的时候,由于记录通常都是按照插入顺序,也就是主键的顺序进行插入的,因此,插入聚集索引是顺序的,不需要随机IO ...

  7. 2021.8.16考试总结[NOIP模拟41]

    T1 你相信引力吗 肯定是单调栈维护.但存在重复值,还是个环,不好搞. 发现取区间时不会越过最大值,因此以最大值为断点将环断为序列.在栈里维护当前栈中有多少个与当前元素相等的元素,小分类讨论一下. 最 ...

  8. [LGP2758]编辑距离

    目录 题目 题目描述 输入格式 输出格式 输入输出样例 题目分析 状态转移方程 初始状态 结束状态 Code 题目 题目描述 设A和B是两个字符串.我们要用最少的字符操作次数,将字符串A转换为字符串B ...

  9. 旋转数组的最小数字 牛客网 剑指Offer

    旋转数组的最小数字 牛客网 剑指Offer 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...

  10. filter tools

    // 过滤商品分类 Vue.filter("cateFilter", (data) => {   let tmp = ["一级分类", "二级分 ...