目录

1. 问题描述

2. 解题分析

3. 代码及测试

4. 思考


1. 问题描述

人们聚集在某个活动会场上,根据到场顺序排成一排等待入场,活动的主办人员,想把人们从队列的某个位置分成两组,想要让分开的两组里至少有一组(原题是每一组)的男女人数都均等。但如果到场顺序不对,可能出现无论怎么分,两组都不能出现男女均等的情况。

举个例子,有3位男性、3位女性以“男男女男女女”的顺序到达,如图所示,无论从队列的哪个位置分开,两组的男女人数都不均等。但如果到场的顺序为“男男女女男女”,那么只需要在第4个人处分组就可以令分开的两组男女人数均等了。

求男性20人、女性10人的情况下,有多少种到场顺序会导致无论怎么分组都没有任何一组的组内男女人数能够均等?(原书中表述的有问题,因为如果要求两组中男女人数都相等,男女总人数就必然相等。而本题题设就是男女人数不等,这样无论按什么顺序到来都满足条件,过于trivial的问题)。

2. 解题分析

按照动态规划的思路进行子问题分解。

令男女人数分别为M(Male)和F(Female),令当前已经到达的男生和女生人数分别为m和f。记这种情况下接下来满足题设要求的人员到来顺序数为g(m,n)。

接下来要么来男生,要么来女生:

(1) 如果来男生的话,则问题变成了子问题g(m+1,f)

(2) 如果来女生的话,则问题变成了子问题g(m,f+1)

因此可以得到递推关系式:

接下来要确定边界条件。

Case1: 如果在某个时刻,到达的男生人数m和女生人数f相等,就相当于找到一个可以“均等分割”的情况(不符合题设且无需继续搜索),因此应该返回0。但是需要注意的是,必须在m>0的条件下以上论断才有效,否则的话,一开始就是m=n=0的情况,这个没有意义。

Case2: 如果在某个时刻,尚未到达的男生人数M-m和尚未到达的女生人数F-f相等,也就相当于找到一个可以“均等分割”的情况(不符合题设且无需继续搜索),因此应该返回0。同样需要注意要在(M-m)>0的条件下以上论断才有效。

Case3: 前两种情况都是属于搜索失败的情况,接下来确定搜索成功的情况。第一感是男生已经到齐而还没有碰到可以平均分割,或者女生已经到齐而还没有碰到可以平均分割,都是属于找不到“均等分割”的情况。但是这里有漏洞。比方说,M=20,F=10,女生已经到达10人,男生只到了9人,此时虽然尚未满足“均等分割”,但是接下来再来一个男生就凑出“均等分割”了。所有还得在以上条件的基础上加上一个约束条件,即任一方(记为A方)已经到齐而另一方((记为B方))到达的人数也不少于A方时,此时没有到达“均等分割”条件,后续只有B方人员到来,就不可能会再出现“均等分割”的情况了。

以下用递归+memoization的方式实现(无它,就是这个代码写起来简单,哪怕效率低一些也值得^-^).

3. 代码及测试

# -*- coding: utf-8 -*-
"""
Created on Sun Aug 29 07:14:15 2021@author: chenxy
"""import sys
import time
import datetime
# import random
from   typing import List
# from   queue import Queue
# from   collections import dequeclass Solution:def noEqualPartition(self, M:int, F:int) -> int:""":M:     The number of boys:F:     The number of girls:ret:   The number of incoming order for no-equal-partition."""               memo = dict()# Recursion core: # Return the number of incoming orders which would satisfy the condition, # when the number of already arrived boys and girls are m and f respectivelydef recursion(m,f):        # print('m,f=',m,f)if (m,f) in memo:return memo[(m,f)]if (m==f) and m>0:memo[(m,f)] = 0return 0if (M-m)==(F-f) and (M-m)>0 : # Found equal partitionmemo[(m,f)] = 0return 0if (M==m and f>=m) or (F==f and (m>=f)):memo[(m,f)] = 1return 1sum = 0if M-m >= 1:sum += recursion(m+1,f)if F-f >= 1:sum += recursion(m,f+1)memo[(m,f)] = sumreturn sumreturn recursion(0,0)
if __name__ == '__main__':        sln    = Solution()    M      = 20F      = 10tStart = time.time()ans    = sln.noEqualPartition(M,F)tCost  = time.time() - tStartprint('M,F={0},{1}, ans={2}, tCost={3:6.3f}(sec)'.format(M,F,ans,tCost)) 

运行结果:

M,F=20,10, ans=2417416, tCost= 0.000(sec)

4. 思考

以上解题过程中其实是磕磕碰碰的,就是说一开始有些细节没有完全想到,导致结果不完全一致。然后可能要经过多次修正才能得到最终正确的答案。这是在已经知道答案的条件下可以这样做。如果没有现成的正确答案呢?那如何来判断吭哧吭哧得到的解答是正确的呢?这个可能是每一个人多多少少都会碰到的问题。有些问题在规模很小的比较容易用纸和笔计算出答案用于程序测试验证,但是并不总是有这么happy的情况,这种情况下怎么办呢?

另外原书以及其它博客中提到最多的估计就是最短路径解法了。。。这个后面再回头补充,先把每一道题都过一遍要紧。

上一篇:Q08: 优秀的机器人

下一篇:Q10: 轮盘的最大值

本系列总目录参见:程序员的算法趣题:详细分析和Python全解

程序员的算法趣题Q09: 落单的男女相关推荐

  1. php算法求出一个数可以被分解成多少个_程序员的算法趣题

    计算机的世界每天都在发生着深刻的变化.新操作系统的发布.CPU性能的提升.智能手机和平板电脑的流行.存储介质的变化.云的普及--这样的变化数不胜数. 在这样日新月异的时代中,"算法" ...

  2. 程序员的算法趣题Q10: 轮盘的最大值

    目录 1. 问题描述 2. 解题分析 3. 代码及测试 1. 问题描述 轮盘游戏被称为"赌场女王".流传较广的轮盘数字排布和设计有"欧式规则"和"美式 ...

  3. 程序员的算法趣题 python3 - (5)

    注:以下题目来自<程序员的算法趣题>– [日]增井敏克著,原书解法主要用Ruby实现,最近在学Python,随便找点东西写写当做练习,准备改成Python3实现,顺便增加一些自己的理解. ...

  4. LeetBook《程序员的算法趣题》Q18---水果酥饼日

    <程序员的算法趣题>-(日)增井敏克 , 书中为69 道数学谜题编写了解题程序, 编程语言为:Ruby,JavaScript,C语言. Q18 水果酥饼日   日本每月的 22 日是水果酥 ...

  5. 程序员的算法趣题Q50: 完美洗牌

    目录 1. 问题描述 2. 解题分析 2.1 思路1 2.2 思路2 3. 代码及测试 4. 后记 1. 问题描述 问题:对2n张牌洗牌,并求当1<=n<=100时,一共有多少个n可以使得 ...

  6. 程序员的算法趣题Q55: 平分蛋糕

    目录 1. 问题描述 2. 解题分析 2.1 初始算法流程 2.2 优化 3. 代码及测试 4. 后记 1. 问题描述 2. 解题分析 这个题目第一感就是动态规划. 对于(m, n)形状(如下图所示, ...

  7. 程序员的算法趣题Q67: 不挨着坐是一种礼节吗?

    目录 1. 问题描述 2. 解题分析 2.1 基本思路 2.2 动态规划 2.3 算法流程 3. 代码及测试 4. 后记 1. 问题描述 注意,本问题不区分人,只考虑各个座位被占用的不同顺序的个数. ...

  8. 程序员的算法趣题Q68: 异性相邻的座位安排(1)

    目录 1. 问题描述 2. 解题分析 3. 代码及测试 4. 后记 1. 问题描述 这道题的描述应该是有问题的(不知道是原文的问题还是翻译的问题). 前面的描述中提到"前后左右的座位全是异性 ...

  9. 程序员的算法趣题Q57: 最快的联络网

    目录 1. 问题描述 2. 解题分析 2.1 学生的状态 2.2 学生状态转移 Case-T1:Do nothing, just wait Case-T2:给处于S0状态的学生打电话 Case-T3: ...

最新文章

  1. SAP QM 模块主数据
  2. CH451 点阵LED显示模块
  3. 关于dotNet加密工具
  4. Servlet 表单数据
  5. 响应式方案调研及前端开发管理思考
  6. mfc打开一个.txt文件并进行处理_文件处理方法Python
  7. 一次FastDFS并发问题的排查经历
  8. 外部表不是预期的格式 解决方案
  9. 认识 URL 及其编码
  10. 第T题 详解放苹果(递归) =========== 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
  11. python公式_魔方字母公式转ABC公式python小工具
  12. 数值方法求解微分方程
  13. 2022年4月树莓派系统初始用户名密码
  14. UNITY中帧动画的制作
  15. Remix OS——一个很有魅力的Android系统
  16. 网易云音乐真的是随机播放吗
  17. 收款机收银机测试流程
  18. Python中的蛇和梯子(单人游戏)
  19. SA、SD、SE 这三者的含义及区分
  20. 无限火力更新服务器公告,英雄联盟更新维护公告

热门文章

  1. java程序:求三个数的最大公约数和最小公倍数
  2. Angular导出功能(excel导出功能、文件数据流导出功能、图片的下载导出功能)
  3. 算法竞赛常用STL库
  4. 微信备份聊天记录,显示连接错误,终极解决办法
  5. 【LeetCode学习计划】《算法-入门-C++》第13天 位运算
  6. 用CSS正确显示人民币符号的HTML转义字符
  7. 大数据分析技术与应用 1
  8. 数据结构(八)——后缀表达式
  9. Map集合及三层嵌套
  10. 以“实景+科幻三维建模渲染”,助力“实景三维中国建设”