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. 手把手教你学Dapr - 1. .Net开发者的大时代

    Dapr全称 Distributed Application Runtime,分布式应用运行时 Dapr的口号 简化云原生应用开发,聚焦在应用的核心逻辑,让代码简单.可移植 Dapr的目标 最佳实践的 ...

  2. 机器学习:EM算法

    EM算法 各类估计 最大似然估计 Maximum Likelihood Estimation,最大似然估计,即利用已知的样本结果,反推最有可能(最大概率)导致这样结果的参数值的计算过程. 直白来讲,就 ...

  3. Beta阶段初始任务分配

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-Beta阶段说明书 一.Beta阶段总体规划 根据用户反馈与测试结果修复alpha版本的bu ...

  4. 热身 for computer industry

    项目 内容 作业属于 班级博客 作业要求 作业要求 个人课程目标 掌握软件工程基础知识 具体有助方面 个人认知与规划 其他参考文献 博客Ⅰ 博客 Ⅱ 选择计算机 你为什么选择计算机专业?你认为你的条件 ...

  5. RocketMQ源码详解 | Producer篇 · 其一:Start,然后 Send 一条消息

    概述 DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name"); ...

  6. MiniFly四轴飞行器之部分系统及电源分析

    最近硬件四轴很火,了解了很久,还是选择了MiniFly,主要还是资料多,后边可以有人讨论,不像很多就是建了个群,研究问题还是在论坛方便很多. 四轴终于拿到手,功能很强大,主要是还支持二次开发,可以研究 ...

  7. 攻防世界 杂项 12.Training-Stegano-1

    题目描述: 这是我能想到的最基础的图片隐写术.啊这 题目分析: 最初还以为直接右击属性查看呢 然后用notepad++看看,一团乱码,结果在最后发现了passwd, 然后这就是flag:stegano ...

  8. 二叉树中和为某一值的路径 牛客网 程序员面试金典 C++ Python

    二叉树中和为某一值的路径 牛客网 程序员面试金典 题目描述 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一 ...

  9. Luogu P1850 [NOIp2016提高组]换教室 | 期望dp

    题目链接 思路: <1>概率与期望期望=情况①的值*情况①的概率+情况②的值*情况②的概率+--+情况n的值*情况n的概率举个例子,抛一个骰子,每一面朝上的概率都是1/6,则这一个骰子落地 ...

  10. 虚拟机克隆后修改mac地址和ip地址

    (1)虚拟机克隆在新的虚拟机下会有文件产生变化. /etc/udev/rules.d/70-persistent-net.rules  文件中会多一个eth1 网卡的文件 ,eth0 的那行文件是原虚 ...