题目描述
«问题描述:
假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。
(1)每次只能在某根柱子的最上面放球。
(2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。
试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。
«编程任务:
对于给定的n,计算在n根柱子上最多能放多少个球。
输入输出格式
输入格式:第1 行有1个正整数n,表示柱子数。
输出格式:程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。
输入输出样例
4
11 1 8 2 7 9 3 6 10 4 5 11
Solution
1.建模思路:
可以发现,对于任意i<j,且i+j=完全平方数的,就连一条有向边(i,j)
该图是有向无环图DAG,求它的最小路径覆盖就行了
理论内容:
- s->Xi,容量为1。
- Xi->Yj,(i, j)∈E,容量上界为1。
- Yi->t,容量上界为1。
DAG的最小路径覆盖=|V|-对应二分图的最大匹配。
约束是什么?对路径的定义中,有至关重要的一点:允许长度为0。于是解的存在性得到了保证。因此,只需满足:对于任意一点,至多有一条与它关联的入边和与它关联的出边被选中。
二分图的匹配,可以从顶点对应的角度看待,也可以从边的角度看待:选出一些边,使得每个顶点至多与一条边关联。和本问题的约束对比,发现有向无环图不是二分图,并且对于顶点而言,边分为入边和出边两类。考虑把点i拆成Xi、Yi,入边连到Yi,出边从Xi出发。这样,问题的约束便和二分图匹配相一致。
目标是什么?使路径覆盖数最小。除了直接数,还能用什么来刻画路径覆盖数?头的数量或尾的数量。什么样的点是头?没有匹配边与对应的Yi关联。尾?没有匹配边与对应的Xi关联。所以,DAG的最小路径覆盖=|V|-对应二分图的最大匹配。
2.细节
这方面的话,每次枚举A,对于1~A的数跑一遍最大匹配(最大流),求出最小路径覆盖,若小于等于柱子数,则A扩大,当A恰好满足最小路径覆盖大于柱子数时,推出循环,输出A-1即可
感觉n较小的话不如打个表吧