动态规划初步探索

来源:互联网 发布:网络算命软件下载 编辑:程序博客网 时间:2024/06/03 02:58

动态规划(dynamic programming),又称dp问题,是求决策过程最优化的数学方法。即把多阶段过程转化为一系列但阶段问题,利用各阶段之间的联系,逐个求解。至于具体的定义百度google一下,这里就不再啰嗦了。简单说一下我自己理解的动态规划,类似于分治法(当然他们肯定不一样),将期待解决的问题分解成若干个子问题,先求子问题,将每个子问题的解存入表中(因为子问题之间不像分治法,分治法子问题之间是没有联系的,而dp问题是有联系的,他的子问题需要用到其他子问题的解),然后最后求得待解决的问题。

 

下面用一个很简单的例子来具体说明一下dp问题的解题过程。题目如下

(地址:http://www.bianchengla.com/course/ds/practise/problem?id=1321):

 

描述

在一个星期三的早上,某同学想用扔硬币的方式来决定是否要去上算法课。

 

他扔 n 次硬币,如果当中有连续 m 次以上(含 m 次)的结果都是正面,那么他就去上课,否则就接着睡觉。(假设每次扔硬币扔出的正反两面的概率都是 0.5。)

输入

输入的每行有一组数据,分别为 n 和 m (0 < n <= 2000, 0 < m <= 10)。输入以 0 0 结尾。

输出

对于每组数据,输出他去上课的概率,四舍五入保留小数点后 2 位。

样例输入
1 12 15 5100 52000 52 30 0
样例输出
0.500.750.030.811.000.00

 

dp问题首先是需要打表,我们根据他的数据要求开一个数组,大小为2001, dp[2001]。这个数组用来存放子问题的解,比如dp[i]就代表投完第i个硬币时,已有连续m个正面的概率。具体假如m是2,dp[0],dp[1]肯定0,因为投币0次或1次不可能出现连续两次正面。

分三种情况讨论:

1. n小于m,即dp数组下标i要小于m的时候,概率值都为0,原因如上所述。

2. 下标i等于m,也就是说n等m,投多少次刚好多少次是正面,这个概率是0.5的m次方

3. 下标i大于m,即n大于m的时候,这个又要分两种情况,概率是这两种情况之和:

(1). 在i之前已经有m次连续了,如果恰好前面第i-1个是连续m次,那第i次如果是正面的话就是连续m+1次符合题目要求,如果第i次是反面的话那恰好就是m次也满足题目,也就是说他第i次无论是正面还是反面都满足条件,所以dp[i]的概率第一种情况由dp[i-1]组成。

(2). 第i次的时候恰好连续了m次,也就是说他前面m-1次都是正面,那他前面m次的那次是必须是一个反面,否则不能刚好在第i次的时候连续m次正面了。他前面m次的那次是一个反面,那个反面的前一次有连续m次的概率是dp[i-(m+1)],那他没有连续m次正面的概率是1-dp[i-(m+1)],他后面的那次是反面,所以概率是0.5然后接着有m次的0.5概率,即总共是0.5的m+1次方。第二种情况的概率是:dp[i-(m+1)]*pow(0.5, m)

所以第三种情况的概率是他们两个之和:dp[i-1]+dp[i-(m+1)]*pow(0.5, m)

下面是具体实现代码:

 

整体思路很简单:分析每个步骤中的概率,然后打表。以后会接着探索dp问题,这篇是dp问题的第一章。