Atcoder abc259
https://atcoder.jp/contests/abc259/tasks/
G - Grid Card Game
题目
HxW的数阵
选择任意的一些行和一些列, 让被选到的所有格子的和最大(同时被行和列选只统计一次)
且 限制条件,如果格子上的值为负那么 不能同时选它的行和列
范围
H,W [1,100]
Aij [-1e9,+1e9]
2s
1024mb
题解
我的思路
显然 纯非负的行和列一定被选,
所以可以预处理让剩下的所有行列至少包含一个负数
然后考虑说纯选行或选列
但是显然有反例
1 | 1 -1 100 |
这种情况 最优的是选1行和1列
然后另一个性质是, 显然 和为非正的行和列不会被选, 因为 如果即选了行又选了列,重叠部分非负 两个都选的和是 小于 两个分别的和的
然后没思路了
题解
首先我们令 结果 = 全部正值 都被选了, 考虑变化对结果的影响
- 如果一个正的没有被选, 那么它的行列没有直接被选, -Aij
- 如果一个负值被选了, 那么它的行和列有一个被选, Aij
如果 Aij < 0 被选了,
如果是行被选, 那么 影响的是 加上 i行的所有负数
如果是列被选, 那么 影响的是 加上 j列的所有负数
于是改变题目
初始分 = 正数和
那么如果 选了i行, 则 损失 i行的所有负值的和
那么如果 选了j列, 则 损失 j列的所有负值的和
对于正的单元没被选的 损失上面值的代价
对于负的单元, 不恩那个同时选行和列
答案 = 正数和 减去 下面网络流的最小割
点:
R[1..H]
C[1..W]
源S,汇T
边:
S->R[i]
, 容量 行i的所有负值和的绝对值
C[j]->T
, 容量 行j的所有负值和的绝对值
R[i] -> C[j]
如果是 Aij > 0, 则 权重 Aij
C[j] -> R[i]
如果是 Aij < 0, 则 权重 无限大
这样考虑
对于 Aij > 0
S->R[i]->C[j]->T
在最小割中, 至少有一条边被割(说至少是因为, 可能 R和T一个集合,S和C一个集合)
对 Aij < 0
也就是最小割一定不会同时割S->R[i]
,和C[j]->T
, 因为如果这样割了
意味着, S,C[j]
是一个集合,R[i],T
是一个集合, 就有 C[j] -> R[i]
的无限大, 就不会是最小割了
对于Aij < 0
一定是 S->R[i]
或 C[j]->T
, 表示
也就是对于Aij < 0, 至多一个成为割边
然后最小割 = 最大流 Dinic, 或者直接调用官方的maxflow
代码
https://atcoder.jp/contests/abc259/submissions/33171094
1 |
|
H/Ex - Yet Another Path Counting
NxN的矩阵
每次向右或向下走
问有多少种路径,头和尾所在位置的数字相同
范围
n 400
aij [1,N^2]
2s
1024 MB
题解
我的思路
最朴素就是 对不同值分开处理,直接变成 每个值=> 所有位置
然后 (i0,j0) => (i1,j1) 就是组合数
问题是, 如果一个一算,是(N^4)的样子会TLE
考虑是否有办法把结果变成统计合并
题解
分块
更朴素的纯色+dp是, O(n^2)的
所以对于每个颜色根据个数来做不同处理
如果当前颜色点个数 <= n
显然用我的思路里两两去算, 复杂度不超过O(个数^2),这一类的总复杂度小于O(sum{个数^2}) <= O(sum{n * 个数})<= O(n * sum{个数}) <= O(n^3)
如果当前颜色个数 > n , 那就直接dp,也不超过O(n^2), 而这种最多n种颜色最多O(n^3)
综上
都在n^3内
代码
https://atcoder.jp/contests/abc259/submissions/35946797
1 |
|
总结
G
感觉 完全对网络流类型不熟,即使看了答案也仅是证明, 感觉没有系统的练习相关的建图, 还是不知道从何而起
这里相当于网络流求的是尽可能删除得小的, 利用了 最小割 = 最大流 , 这也是一个点,要求最小值的时候可以考虑让图能含义到最小割
然后就是atcoder内置的maxflow真香啊
Ex
有一说一感觉比G简单
这个分类的第一个复杂度上限推导还是很有意思,有点像之前树上左右部分平方的dp总复杂度是n3不是n4的感觉