棋盘无五子相连问题最优性证明

来源:互联网 发布:淘宝客内部优惠券源码 编辑:程序博客网 时间:2024/05/16 07:39

问题描述:在一个的棋盘中至少去掉多少格子,使得棋盘中不会出现5子相连(包括水平、垂直、对角)的情况?

此问题最初出处已无从考证,但它的解题思想却非常的经典,这就是数学里面的局部整体原则(注意:这里并不是特指代数数论里面Hasse-Minkowski的定理)。我们可以从对局部问题的考察获得一个局部解,然后将其推广到整体的情形。 我们先考察一个最简单的情况,即的情况: 

容易知道此时我们只需去掉:(0,4)、(1,2)、(2,0)、(3,3)、(4,1)这几个方格即可(注:这里的去掉方式并不唯一,但为了扩展的需要我们选择如上几个格点),如下图所示:

                         

进一步,由于要保证每列都至少有一个方格去掉,所以在时去掉的最小方格数即为5。这启发我们猜想一般情况下的解为:,我们接下来证明这是充分必要的:


首先若m,n均被5整除,那么可以将大棋盘分成个5*5的小棋盘,由上面的讨论知此时至少要去掉个方格(因为每个小棋盘至少去掉5个方格),我们接下来证明对每个小棋盘按照如上去除方法即可保证大棋盘无五子相连。这等价为证明对任意均有解(即其均可经过如上去掉的小方格),事实上通过不复杂计算我们可以得到如上去掉的点的横纵坐标的和差均通过模5剩余类,这证明了上面的论断。

接下来我们用归纳法证明一般情况:对于m,n小于10的情况验证即可,当时根据以下式子

我们可以将大棋盘分为m*(n-5)和m*5的两个棋盘,根据归纳假设前者至少去掉个方格,后者至少去掉个,因此从上面的等式我们可得到大棋盘至少要去掉个方格。我们只需证明这是充分的即可,这是因为我们可以将棋盘扩张到5m*5n,此时由第一部分证明知其去掉5mn个方格是可行的,但这些方格分布在25个m*n棋盘中,因此至少有一个棋盘的方格数不多于。至此,我们证明了我们的整个猜想!

所以关于此问题我们只需以下几行代码即可解决:

#include<stdio.h>int main(){   int m,n;   while(scanf("%d%d",&m,&n)==2)      printf("%d\n",(m*n)/5);   return 0;}



0 0
原创粉丝点击