近期从网上看到一个算法题,感觉蛮有意思的,就研究了吧,题目如下:
某种传染病第一天只有一个患者,前五天为潜伏期,不发作也不会传染人,第6天开始发作,从发作到治愈需要5天时间,期间每天传染3个人,求第N天共有多少患者。
现将自己的分析求解过程分享如下,跟大家一起探讨学习,有不对的地方,忘请指教。
直接上代码,分析过程在头注释里:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
/*
* 某种传染病第一天只有一个患者,前五天为潜伏期,不发作也不会传染人
* 第6天开始发作,从发作到治愈需要5天时间,期间每天传染3个人求第N天
* 共有多少患者
*/
/*
* 解答思路:递归推理建立数学模型
* 根据题目将患者分为潜伏期病人和发作期病人,那假设第n天的潜伏期患者为f(n),
* 再假设第n天的发作期患者为y(n),则最后的总患者数应该=f(n) + y(n).
* 下面我们来分析下前一天的潜伏期患者f(n-1)同f(n)的关系,以及前一天的发作期
* 患者y(n-1)同y(n)的关系,然后来建立数学模型。因为病情的变化是以5天为一个变化周期,其中就存在
* 以下几个变化量:
* △f:从n-1天到n天潜伏期患者的新感染数量
* △c:从n-1天到n天由潜伏期转发作期的患者数量
* △y:从n-1天到n天康复的患者数量
* 有了以上几个变化量,我们可以简单列出前后两天的两种患者的数量的变化关系:
* f(n-1)-△c+△f=f(n)----------(1)
* y(n-1)+△c-△y=y(n)----------(2)
* 下面的关键就是求解以上的三个增量,我们要利用两个重要的已知条件,一个是发作期的患者每天传染3
* 个新患者,二是5天一个病情(包括新感染进入潜伏期、由潜伏期变为发作期以及康复)变化期,所以我们
* 能得到:
* △f=3*y(n)
* △c稍微有点难度,仔细分析下是可以得到的,第n天的进入发作期的患者,正是5天前刚进入潜伏期的
* 患者数3*y(n-5),所以
* △c=3*y(n-5)
* 所以至此公式(1)已经出来了,为:
* f(n-1)-3*y(n-5)+3*y(n)=f(n)---------(3)
* 下面还有(2)中还有个△y未解,这个有点难度,我们来推理下,要求第n天的康复患者数,可以推理为求
* 第n-5天的新进入发作期的患者数,我们设这个数为x,然后利用公式(1)可以来推导出第n-5天的时候的潜伏期
* 的变化关系为
* f(n-6)-x+3*y(n-5)=f(n-5) => x=f(n-5)-f(n-6)-3*y(n-5),故△y=x即为
* △y=f(n-5)-f(n-6)-3*y(n-5)
* 以上变化量的求解是建立数学模型的关键。这样将△y代入公式(2),并化简得到:
* y(n-1)+f(n-5)-f(n-6)=y(n)-----------(4)
* 自此公式(3)和(4)即为最终的数学模型,编码中的递归推导按照此公式来即可求解,
* f(n)对应PreSick(int n)递归方法,y(n)对应Sick(int n)递归方法。需要注意的是
* 对于n<7以下的递归结束条件下,要给出直接的数字。
*/
class Program
{
static void Main(string[] args)
{
string inputDays = Console.ReadLine();
int n = Convert.ToInt32(inputDays);
int HowMany = PreSick(n) + Sick(n);
Console.WriteLine(HowMany);
}
static int PreSick(int n)
{
if (n == 7)
{
return 6;
}
else if (n == 6)
{
return 3;
}
else if (n < 6)
{
return 1;
}
else
{
//f(n)=f(n-1)-3*y(n-5)+3*y(n)---------(3)
return PreSick(n - 1) - 3 * Sick(n - 5) + 3 * Sick(n);
}
}
static int Sick(int n)
{
if (n < 7 && n > 5)
{
return 1;
}
else if (n <= 5)
{
return 0;
}
else
{
//y(n)=y(n-1)+f(n-5)-f(n-6)-----------(4)
return Sick(n-1) -PreSick(n-6) + PreSick(n-5);
}
}
}
}