[网络流专练4][魔术球问题]

题目描述

«问题描述:

假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球。

(1)每次只能在某根柱子的最上面放球。

(2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数。

试设计一个算法,计算出在n根柱子上最多能放多少个球。例如,在4 根柱子上最多可放11 个球。

«编程任务:

对于给定的n,计算在n根柱子上最多能放多少个球。

输入输出格式

输入格式:

第1 行有1个正整数n,表示柱子数。

输出格式:

程序运行结束时,将n 根柱子上最多能放的球数以及相应的放置方案输出。文件的第一行是球数。接下来的n行,每行是一根柱子上的球的编号。

输入输出样例

输入样例#1:
4
输出样例#1:
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较小的话不如打个表吧

posted @ 2016-12-29 21:17  keshuqi  阅读(249)  评论(0编辑  收藏  举报